diff --git a/ActiveSync/NGVCard+ActiveSync.m b/ActiveSync/NGVCard+ActiveSync.m index bb4f29248..eb62b9722 100644 --- a/ActiveSync/NGVCard+ActiveSync.m +++ b/ActiveSync/NGVCard+ActiveSync.m @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import #import +#import #import @@ -193,11 +194,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if ((o = [self note])) { + // It is very important here to NOT set 0 in the response, + // otherwise it'll prevent WP8 phones from sync'ing. See #3028 for details. o = [o activeSyncRepresentationInContext: context]; [s appendString: @""]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", [o length]]; - [s appendFormat: @"%d", 0]; [s appendFormat: @"%@", o]; [s appendString: @""]; } @@ -222,14 +224,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [self setNote: o]; // Categories - if ((o = [theValues objectForKey: @"Categories"])) + if ((o = [theValues objectForKey: @"Categories"]) && [o length]) [self setCategories: o]; // Birthday if ((o = [theValues objectForKey: @"Birthday"])) { o = [o calendarDate]; - [self setBday: [o descriptionWithCalendarFormat: @"%Y-%m-%d"]]; + [self setBday: [o descriptionWithCalendarFormat: @"%Y-%m-%d" timeZone: nil locale: nil]]; } // diff --git a/ActiveSync/NSData+ActiveSync.m b/ActiveSync/NSData+ActiveSync.m index abd91995a..7114403cc 100644 --- a/ActiveSync/NSData+ActiveSync.m +++ b/ActiveSync/NSData+ActiveSync.m @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import +#import #include #include @@ -48,7 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. path = [NSString stringWithFormat: @"/tmp/%@.data", [[NSProcessInfo processInfo] globallyUniqueString]]; [self writeToFile: path atomically: YES]; - NSLog(@"Original data written to: %@", path); + [self errorWithFormat: @"Original data written to: %@", path]; } // @@ -81,20 +82,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (ret != WBXML_OK) { - NSLog(@"wbxml2xmlFromContent: failed: %s\n", wbxml_errors_string(ret)); + [self errorWithFormat: @"wbxml2xmlFromContent: failed: %s\n", wbxml_errors_string(ret)]; [self _dumpToFile]; return nil; } - data = [[NSData alloc] initWithBytes: xml length: xml_len]; + data = [NSData dataWithBytesNoCopy: xml length: xml_len freeWhenDone: YES]; #if WBXMLDEBUG [data writeToFile: @"/tmp/protocol.decoded" atomically: YES]; #endif - free(xml); - - return AUTORELEASE(data); + return data; } @@ -116,7 +115,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (ret != WBXML_OK) { - NSLog(@"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret)); + [self logWithFormat: @"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret)]; [self _dumpToFile]; return nil; } @@ -131,22 +130,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (ret != WBXML_OK) { - NSLog(@"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret)); + [self errorWithFormat: @"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret)]; [self _dumpToFile]; free(wbxml); wbxml_conv_xml2wbxml_destroy(conv); return nil; } - data = [[NSData alloc] initWithBytes: wbxml length: wbxml_len]; + data = [NSData dataWithBytesNoCopy: wbxml length: wbxml_len freeWhenDone: YES]; #if WBXMLDEBUG [data writeToFile: @"/tmp/protocol.encoded" atomically: YES]; #endif - free(wbxml); wbxml_conv_xml2wbxml_destroy(conv); - - return AUTORELEASE(data); + + return data; } @end diff --git a/ActiveSync/NSString+ActiveSync.m b/ActiveSync/NSString+ActiveSync.m index 1007c4bde..01f593352 100644 --- a/ActiveSync/NSString+ActiveSync.m +++ b/ActiveSync/NSString+ActiveSync.m @@ -33,11 +33,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include +#include +#include #include +static NSArray *easCommandCodes = nil; +static NSArray *easCommandParameters = nil; + @implementation NSString (ActiveSync) - (NSString *) sanitizedServerIdWithType: (SOGoMicrosoftActiveSyncFolderType) folderType @@ -61,9 +67,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { NSString *s; - s = [self stringByEscapingHTMLString]; + s = [self safeString]; - return [s safeString]; + return [s stringByEscapingHTMLString]; } - (int) activeSyncFolderType @@ -122,23 +128,98 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // - (NSCalendarDate *) calendarDate { + NSString *s; id o; - o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y%m%dT%H%M%SZ"]; + // We force parsing in the GMT timezone. If we don't do that, the date will be parsed + // in the default timezone. + s = [NSString stringWithFormat: @"%@ GMT", self]; + o = [NSCalendarDate dateWithString: s calendarFormat: @"%Y%m%dT%H%M%SZ %Z"]; if (!o) - o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ"]; - + o = [NSCalendarDate dateWithString: s calendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ %Z"]; + return o; } - (NSString *) _valueForParameter: (NSString *) theParameter { - NSArray *components; + NSMutableArray *components; NSString *s; int i; - components = [[[self componentsSeparatedByString: @"?"] lastObject] componentsSeparatedByString: @"&"]; + components = [NSMutableArray arrayWithArray: [[[self componentsSeparatedByString: @"?"] lastObject] componentsSeparatedByString: @"&"]]; + + // We handle BASE64 encoded queryStrings. See http://msdn.microsoft.com/en-us/library/ee160227%28v=exchg.80%29.aspx for details. + if ([components count] == 1) + { + NSString *deviceType, *parameterValue; + NSData *queryString; + + int cmd_code, deviceid_length, policy_length, devicetype_length, parameter_code, parameter_length, i; + const char* qs_bytes; + + queryString = [[components objectAtIndex: 0] dataByDecodingBase64]; + + if (![queryString length]) + return nil; + + qs_bytes = (const char*)[queryString bytes]; + + if (!easCommandCodes) + { + easCommandCodes = [NSArray arrayWithObjects:@"Sync", @"SendMail", @"SmartForward", @"SmartReply", @"GetAttachment", @"na", @"na", @"na", @"na", + @"FolderSync", @"FolderCreate", @"FolderDelete", @"FolderUpdate", @"MoveItems", @"GetItemEstimate", @"MeetingResponse", + @"Search", @"Settings", @"Ping", @"ItemOperations", @"Provision", @"ResolveRecipients", @"ValidateCert", nil]; + RETAIN(easCommandCodes); + } + + if (!easCommandParameters) + { + easCommandParameters = [NSArray arrayWithObjects:@"AttachmentName", @"CollectionId", @"na", @"ItemId", @"LongId", @"na", @"Occurrence", @"Options", @"User", nil]; + RETAIN(easCommandParameters); + } + + // Command code, 1 byte, ie.: cmd= + cmd_code = qs_bytes[1]; + [components addObject: [NSString stringWithFormat: @"cmd=%@", [easCommandCodes objectAtIndex: cmd_code]]]; + + // Device ID length and Device ID (variable) + deviceid_length = qs_bytes[4]; + [components addObject: [NSString stringWithFormat: @"deviceId=%@", [[NSData encodeDataAsHexString: [queryString subdataWithRange: NSMakeRange(5, deviceid_length)]] uppercaseString]]]; + + // Device type length and type (variable) + policy_length = qs_bytes[5+deviceid_length]; + devicetype_length = qs_bytes[5+deviceid_length+1+policy_length]; + deviceType = [[NSString alloc] initWithData: [queryString subdataWithRange: NSMakeRange(5+deviceid_length+1+policy_length+1, devicetype_length)] + encoding: NSASCIIStringEncoding]; + AUTORELEASE(deviceType); + + [components addObject: [NSString stringWithFormat: @"deviceType=%@", deviceType]]; + + // Command Parameters + i = 5+deviceid_length+1+policy_length+1+devicetype_length; + + while (i < [queryString length]) + { + parameter_code = qs_bytes[i]; + parameter_length = qs_bytes[i+1]; + parameterValue = [[NSString alloc] initWithData: [queryString subdataWithRange: NSMakeRange(i+1+1, parameter_length)] + encoding: NSASCIIStringEncoding]; + + AUTORELEASE(parameterValue); + + // parameter_code 7 == Options + // http://msdn.microsoft.com/en-us/library/ee237789(v=exchg.80).aspx + if (parameter_code == 7) + [components addObject: [NSString stringWithFormat: @"%@=%@", [easCommandParameters objectAtIndex: parameter_code], + ([parameterValue isEqualToString: @"\001"]) ? @"SaveInSent" : @"AcceptMultiPart"]]; + else + [components addObject: [NSString stringWithFormat: @"%@=%@", [easCommandParameters objectAtIndex: parameter_code], parameterValue]]; + + i = i + 1 + 1 + parameter_length; + } + } for (i = 0; i < [components count]; i++) { diff --git a/ActiveSync/README b/ActiveSync/README index 0bdb38085..a261d48f3 100644 --- a/ActiveSync/README +++ b/ActiveSync/README @@ -4,7 +4,7 @@ to negotiate the fees associated to your user base. To contact Microsoft, please visit: -http://www.microsoft.com/en-us/legal/intellectualproperty/IPLicensing/Programs/exchangeactivesyncprotocol.aspx +http://www.microsoft.com/en-us/legal/intellectualproperty/ and send an email to iplicreq@microsoft.com diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m index 024b2a2a7..2c353f736 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m +++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m @@ -29,11 +29,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "SOGoActiveSyncDispatcher+Sync.h" - #import +#import #import #import #import +#import #import #import #import @@ -56,6 +57,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import +#import #import #import @@ -114,22 +116,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. forKey: (NSString *) theFolderKey { SOGoCacheGCSObject *o; + NSDictionary *values; NSString *key; key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], theFolderKey]; - + values = [theFolderMetadata copy]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; [o setObjectType: ActiveSyncFolderCacheObject]; [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; - + //[o reloadIfNeeded]; + [[o properties] removeObjectForKey: @"SyncKey"]; [[o properties] removeObjectForKey: @"SyncCache"]; [[o properties] removeObjectForKey: @"DateCache"]; [[o properties] removeObjectForKey: @"MoreAvailable"]; + [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; - [[o properties] addEntriesFromDictionary: theFolderMetadata]; + [[o properties] addEntriesFromDictionary: values]; [o save]; + [values release]; } - (NSMutableDictionary *) _folderMetadataForKey: (NSString *) theFolderKey @@ -147,6 +153,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. return [o properties]; } +- (NSString *) _getNameInCache: (id) theCollection withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType +{ + NSString *nameInCache; + + if (theFolderType == ActiveSyncMailFolder) + nameInCache= [[[theCollection mailAccountFolder] imapFolderGUIDs] objectForKey: [theCollection nameInContainer]]; + else + { + NSString *component_name; + if (theFolderType == ActiveSyncContactFolder) + component_name = @"vcard"; + else if (theFolderType == ActiveSyncEventFolder) + component_name = @"vevent"; + else + component_name = @"vtodo"; + + nameInCache= [NSString stringWithFormat: @"%@/%@", component_name, [theCollection nameInContainer]]; + } + + return nameInCache; +} + + // // @@ -190,7 +219,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType inBuffer: (NSMutableString *) theBuffer { - NSMutableDictionary *allValues; + NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *allValues; NSString *clientId, *serverId; NSArray *additions; @@ -259,9 +288,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. case ActiveSyncMailFolder: default: { - // FIXME - //continue; - NSLog(@"BLARG!"); + // FIXME - what to do? + [self errorWithFormat: @"Fatal error occured - tried to call -processSyncAddCommand: ... on a mail folder. We abort."]; abort(); } } @@ -276,6 +304,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [theBuffer appendFormat: @"%@", serverId]; [theBuffer appendFormat: @"%d", 1]; [theBuffer appendString: @""]; + + // Update syncCache + folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]]; + + syncCache = [folderMetadata objectForKey: @"SyncCache"]; + dateCache = [folderMetadata objectForKey: @"DateCache"]; + + [syncCache setObject: [folderMetadata objectForKey: @"SyncKey"] forKey: serverId]; + [dateCache setObject: [NSCalendarDate date] forKey: serverId]; + + [self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]]; } } } @@ -375,6 +414,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } } + [theBuffer appendString: @""]; + [theBuffer appendFormat: @"%@", serverId]; + [theBuffer appendFormat: @"%d", 1]; + [theBuffer appendString: @""]; } } } @@ -431,6 +474,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (![sogoObject isKindOfClass: [NSException class]]) [sogoObject delete]; + + [theBuffer appendString: @""]; + [theBuffer appendFormat: @"%@", serverId]; + [theBuffer appendFormat: @"%d", 1]; + [theBuffer appendString: @""]; + + // update syncCache + NSMutableDictionary *folderMetadata, *dateCache, *syncCache; + folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]]; + + syncCache = [folderMetadata objectForKey: @"SyncCache"]; + dateCache = [folderMetadata objectForKey: @"DateCache"]; + + [syncCache removeObjectForKey: serverId]; + [dateCache removeObjectForKey: serverId]; + + [self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]]; } } } @@ -471,6 +531,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processSyncGetChanges: (id ) theDocumentElement inCollection: (id) theCollection withWindowSize: (unsigned int) theWindowSize + withMaxSyncResponseSize: (unsigned int) theMaxSyncResponseSize withSyncKey: (NSString *) theSyncKey withFolderType: (SOGoMicrosoftActiveSyncFolderType) theFolderType withFilterType: (NSCalendarDate *) theFilterType @@ -479,6 +540,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { NSMutableDictionary *folderMetadata, *dateCache, *syncCache; + NSAutoreleasePool *pool; NSMutableString *s; BOOL more_available; @@ -488,18 +550,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. more_available = NO; - if (theFolderType == ActiveSyncMailFolder && !([theSyncKey isEqualToString: @"-1"]) && theFilterType) + folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]]; + + // If this is a new sync operation, DateCache and SyncCache needs to be deleted + if ([theSyncKey isEqualToString: @"-1"]) + { + [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"]; + [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"]; + } + + syncCache = [folderMetadata objectForKey: @"SyncCache"]; + dateCache = [folderMetadata objectForKey: @"DateCache"]; + + if ((theFolderType == ActiveSyncMailFolder || theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder) && + !([folderMetadata objectForKey: @"MoreAvailable"]) && // previous sync operation reached the windowSize or maximumSyncReponseSize + !([theSyncKey isEqualToString: @"-1"]) && // new sync operation + theFilterType) { NSArray *allKeys; NSString *key; + int softdelete_count; softdelete_count = 0; - folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]]; - dateCache = [folderMetadata objectForKey: @"DateCache"]; - syncCache = [folderMetadata objectForKey: @"SyncCache"]; - allKeys = [dateCache allKeys]; for (i = 0; i < [allKeys count]; i++) { @@ -510,17 +584,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [s appendString: @""]; [s appendFormat: @"%@", key]; [s appendString: @""]; - + [syncCache removeObjectForKey: key]; [dateCache removeObjectForKey: key]; softdelete_count++; } - if (softdelete_count >= theWindowSize) + if (softdelete_count >= theWindowSize || (theMaxSyncResponseSize > 0 && [s length] >= theMaxSyncResponseSize)) { [folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"]; - [self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]]; + [self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]]; more_available = YES; *theLastServerKey = theSyncKey; @@ -532,7 +606,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } [folderMetadata removeObjectForKey: @"MoreAvailable"]; - [self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]]; + [self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]]; } // @@ -557,7 +631,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSArray *allComponents; BOOL updated; - int deleted; + int deleted, return_count; if (theFolderType == ActiveSyncContactFolder) component_name = @"vcard"; @@ -567,39 +641,67 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. component_name = @"vtodo"; allComponents = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType]; + allComponents = [allComponents sortedArrayUsingDescriptors: [NSArray arrayWithObjects: [[NSSortDescriptor alloc] initWithKey: @"c_lastmodified" ascending:YES], nil]]; + // Check for the WindowSize max = [allComponents count]; - // Disabled for now for GCS folders. - // if (max > theWindowSize) - // { - // max = theWindowSize; - // more_available = YES; - // } - + return_count = 0; + for (i = 0; i < max; i++) { + pool = [[NSAutoreleasePool alloc] init]; + + // Check for the WindowSize and slice accordingly + if (return_count >= theWindowSize || (theMaxSyncResponseSize > 0 && [s length] >= theMaxSyncResponseSize)) + { + more_available = YES; + + // -1 to make sure that we miss no event in case there are more with the same c_lastmodified + *theLastServerKey = [[NSString alloc] initWithFormat: @"%d", [[component objectForKey: @"c_lastmodified"] intValue] - 1]; + + DESTROY(pool); + break; + } + component = [allComponents objectAtIndex: i]; deleted = [[component objectForKey: @"c_deleted"] intValue]; if (!deleted && ![[component objectForKey: @"c_component"] isEqualToString: component_name]) - continue; + { + DESTROY(pool); + continue; + } uid = [[component objectForKey: @"c_name"] sanitizedServerIdWithType: theFolderType]; if (deleted) { - [s appendString: @""]; - [s appendFormat: @"%@", uid]; - [s appendString: @""]; + if ([syncCache objectForKey: uid]) + { + [s appendString: @""]; + [s appendFormat: @"%@", uid]; + [s appendString: @""]; + + [syncCache removeObjectForKey: uid]; + [dateCache removeObjectForKey: uid]; + return_count++; + } } else { updated = YES; - if ([[component objectForKey: @"c_creationdate"] intValue] > [theSyncKey intValue]) + if (![syncCache objectForKey: uid]) updated = NO; + else if ([[component objectForKey: @"c_lastmodified"] intValue] == [[syncCache objectForKey: uid] intValue]) + { + DESTROY(pool); + continue; + } + + return_count++; sogoObject = [theCollection lookupName: [uid sanitizedServerIdWithType: theFolderType] inContext: context @@ -610,7 +712,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. else componentObject = [sogoObject component: NO secure: NO]; - // // We do NOT synchronize NEW events that are in fact, invitations // to events. This is due to the fact that Outlook 2013 creates @@ -632,9 +733,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. partstat = [attendee participationStatus]; if (partstat == iCalPersonPartStatNeedsAction) - continue; + { + DESTROY(pool); + continue; + } } } + + [syncCache setObject: [component objectForKey: @"c_lastmodified"] forKey: uid]; + + // No need to set dateCache for Contacts + if ((theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder)) + { + NSCalendarDate *d; + + if ([[component objectForKey: @"c_cycleenddate"] intValue]) + d = [NSCalendarDate dateWithTimeIntervalSince1970: [[component objectForKey: @"c_cycleenddate"] intValue]]; + else if ([[component objectForKey: @"c_enddate"] intValue]) + d = [NSCalendarDate dateWithTimeIntervalSince1970: [[component objectForKey: @"c_enddate"] intValue]]; + else + d = [NSCalendarDate distantFuture]; + + [dateCache setObject: d forKey: uid]; + } if (updated) [s appendString: @""]; @@ -652,13 +773,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [s appendString: @""]; else [s appendString: @""]; - } - } // for ... - folderMetadata = [NSDictionary dictionaryWithObject: [theCollection davCollectionTag] - forKey: @"SyncKey"]; + return_count++; + } + + DESTROY(pool); + } // for (i = 0; i < max; i++) ... + + if (more_available) + { + [folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"]; + [folderMetadata setObject: *theLastServerKey forKey: @"SyncKey"]; + } + else + { + [folderMetadata removeObjectForKey: @"MoreAvailable"]; + [folderMetadata setObject: [theCollection davCollectionTag] forKey: @"SyncKey"]; + } + [self _setFolderMetadata: folderMetadata forKey: [NSString stringWithFormat: @"%@/%@", component_name, [theCollection nameInContainer]]]; + + RELEASE(*theLastServerKey); } break; case ActiveSyncMailFolder: @@ -673,7 +809,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int j, k, return_count; BOOL found_in_cache; - allMessages = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType]; max = [allMessages count]; @@ -685,27 +820,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sequence: [[[allMessages objectAtIndex: i] allValues] lastObject]]]; } - // If it's a new Sync operation, DateCache and SyncCache need to be deleted - // but GUID stored by folderSync shouldn't be touched - folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]]; - if ([theSyncKey isEqualToString: @"-1"]) - { - [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"]; - [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"]; - } - - // Check whether GUID in cache is equal to the GUID from imap - this is to avoid cache corruptions if a folder has been renamed and a new folder - // with the same name has been created but folderSync has not yet updated the cache - if (!([[theCollection nameInContainer] isEqualToString: - [NSString stringWithFormat: @"folder%@", [self globallyUniqueIDToIMAPFolderName: [folderMetadata objectForKey: @"GUID"] type: theFolderType]]])) - { - NSLog(@"GUID mismatch don't sync now!"); - return; - } - - syncCache = [folderMetadata objectForKey: @"SyncCache"]; - dateCache = [folderMetadata objectForKey: @"DateCache"]; - sortedBySequence = [[NSMutableArray alloc] initWithDictionary: syncCache]; [sortedBySequence sortUsingSelector: @selector(compareSequence:)]; [sortedBySequence autorelease]; @@ -732,7 +846,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. else found_in_cache = NO; - if (found_in_cache) k = j+1; else @@ -747,15 +860,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. for (; k < [allCacheObjects count]; k++) { + pool = [[NSAutoreleasePool alloc] init]; + // Check for the WindowSize and slice accordingly - if (return_count >= theWindowSize) + if (return_count >= theWindowSize || (theMaxSyncResponseSize > 0 && [s length] >= theMaxSyncResponseSize)) { NSString *lastSequence; more_available = YES; lastSequence = ([[aCacheObject sequence] isEqual: [NSNull null]] ? @"1" : [aCacheObject sequence]); - *theLastServerKey = [NSString stringWithFormat: @"%@-%@", [aCacheObject uid], lastSequence]; + *theLastServerKey = [[NSString alloc] initWithFormat: @"%@-%@", [aCacheObject uid], lastSequence]; //NSLog(@"Reached windowSize - lastUID will be: %@", *theLastServerKey); + DESTROY(pool); break; } @@ -836,7 +952,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } } - } + DESTROY(pool); + } // for (; k < ...) if (more_available) { @@ -849,8 +966,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [folderMetadata setObject: [theCollection davCollectionTag] forKey: @"SyncKey"]; } - [self _setFolderMetadata: folderMetadata - forKey: [theCollection nameInContainer]]; + [self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]]; + RELEASE(*theLastServerKey); + } // default: break; } // switch (folderType) ... @@ -862,9 +980,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [theBuffer appendString: @""]; [theBuffer appendString: s]; [theBuffer appendString: @""]; - - if (more_available) - [theBuffer appendString: @""]; } } @@ -904,7 +1019,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if ([[element tagName] isEqualToString: @"Add"]) { // Add - [self processSyncAddCommand: aCommand + [self processSyncAddCommand: element inCollection: theCollection withType: theFolderType inBuffer: theBuffer]; @@ -913,7 +1028,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. else if ([[element tagName] isEqualToString: @"Change"]) { // Change - [self processSyncChangeCommand: aCommand + [self processSyncChangeCommand: element inCollection: theCollection withType: theFolderType inBuffer: theBuffer]; @@ -922,15 +1037,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. else if ([[element tagName] isEqualToString: @"Delete"]) { // Delete - [self processSyncDeleteCommand: aCommand + [self processSyncDeleteCommand: element inCollection: theCollection withType: theFolderType inBuffer: theBuffer]; + *processed = YES; } else if ([[element tagName] isEqualToString: @"Fetch"]) { // Fetch - [self processSyncFetchCommand: aCommand + [self processSyncFetchCommand: element inCollection: theCollection withType: theFolderType inBuffer: theBuffer]; @@ -947,14 +1063,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processSyncCollection: (id ) theDocumentElement inBuffer: (NSMutableString *) theBuffer changeDetected: (BOOL *) changeDetected + maxSyncResponseSize: (int) theMaxSyncResponseSize { - NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey; + NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey, *syncKeyInCache; SOGoMicrosoftActiveSyncFolderType folderType; id collection, value; NSMutableString *changeBuffer, *commandsBuffer; BOOL getChanges, first_sync; - unsigned int windowSize, v; + unsigned int windowSize, v, status; + NSMutableDictionary *folderMetadata; changeBuffer = [NSMutableString string]; commandsBuffer = [NSMutableString string]; @@ -965,6 +1083,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. collection = [self collectionFromId: realCollectionId type: folderType]; syncKey = davCollectionTag = [[(id)[theDocumentElement getElementsByTagName: @"SyncKey"] lastObject] textValue]; + + if (collection == nil) + { + // Collection not found - next folderSync will do the cleanup + //NSLog(@"Sync Collection not found %@ %@", collectionId, realCollectionId); + //Outlook doesn't like following response + //[theBuffer appendString: @""]; + //[theBuffer appendFormat: @"%@", syncKey]; + //[theBuffer appendFormat: @"%@", collectionId]; + //[theBuffer appendFormat: @"%d", 8]; + //[theBuffer appendString: @""]; + return; + } // We check for a window size, default to 100 if not specfied or out of bounds windowSize = [[[(id)[theDocumentElement getElementsByTagName: @"WindowSize"] lastObject] textValue] intValue]; @@ -978,6 +1109,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. windowSize = v; lastServerKey = nil; + status = 1; // From the documention, if GetChanges is missing, we must assume it's a YES. // See http://msdn.microsoft.com/en-us/library/gg675447(v=exchg.80).aspx for all details. @@ -995,6 +1127,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. first_sync = YES; *changeDetected = YES; } + else if ((![syncKey isEqualToString: @"-1"]) && !([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"SyncCache"])) + { + //NSLog(@"Reset folder: %@", [collection nameInContainer]); + davCollectionTag = @"0"; + first_sync = YES; + *changeDetected = YES; + + if (!([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"displayName"])) + status = 12; // need folderSync + else + status = 3; // do a complete resync + } // We check our sync preferences and we stash them bodyPreferenceType = [[(id)[[(id)[theDocumentElement getElementsByTagName: @"BodyPreference"] lastObject] getElementsByTagName: @"Type"] lastObject] textValue]; @@ -1004,7 +1148,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [context setObject: bodyPreferenceType forKey: @"BodyPreferenceType"]; - // We generate the commands, if any, for the response. We might also have // generated some in processSyncCommand:inResponse: as we could have // received a Fetch command @@ -1013,6 +1156,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [self processSyncGetChanges: theDocumentElement inCollection: collection withWindowSize: windowSize + withMaxSyncResponseSize: theMaxSyncResponseSize withSyncKey: syncKey withFolderType: folderType withFilterType: [NSCalendarDate dateFromFilterType: [[(id)[theDocumentElement getElementsByTagName: @"FilterType"] lastObject] textValue]] @@ -1037,27 +1181,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. inBuffer: s processed: &processed]; - if (processed) + // Windows phons don't empty Responses tags - such as: . + // We onnly generate this tag when the command has generated a response. + if (processed && [s length]) [commandsBuffer appendFormat: @"%@", s]; - else - [commandsBuffer appendString: s]; } + folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]]; + // If we got any changes or if we have applied any commands // let's regenerate our SyncKey based on the collection tag. if ([changeBuffer length] || [commandsBuffer length]) { if (lastServerKey) davCollectionTag = lastServerKey; - else if (![[self _folderMetadataForKey: [collection nameInContainer]] objectForKey: @"MoreAvailable"]) - davCollectionTag = [collection davCollectionTag]; - + else + { + // Use the SyncKey saved by processSyncGetChanges - if processSyncGetChanges is not called (because of getChanges=false) + // SyncKey has the value of the previous sync operation. + davCollectionTag = [folderMetadata objectForKey: @"SyncKey"]; + + if (!davCollectionTag) + davCollectionTag = [collection davCollectionTag]; + } + *changeDetected = YES; } else { - if (folderType == ActiveSyncMailFolder && [syncKey isEqualToString: @"-1"]) - davCollectionTag = [collection davCollectionTag]; + // Make sure that client is updated with the right syncKey. - This keeps vtodo's and vevent's syncKey in sync. + syncKeyInCache = [folderMetadata objectForKey: @"SyncKey"]; + if (syncKeyInCache && !([davCollectionTag isEqualToString:syncKeyInCache])) + { + davCollectionTag = syncKeyInCache; + *changeDetected = YES; + } } // Generate the response buffer @@ -1074,10 +1232,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [theBuffer appendFormat: @"%@", davCollectionTag]; [theBuffer appendFormat: @"%@", collectionId]; - [theBuffer appendFormat: @"%d", 1]; + [theBuffer appendFormat: @"%d", status]; + + // MoreAvailable breaks Windows Mobile devices if not between and + // https://social.msdn.microsoft.com/Forums/en-US/040b254e-f47e-4cc1-a397-6d8393cdb819/airsyncmoreavailable-breaks-windows-mobile-devices-what-am-i-doing-wrong?forum=os_exchangeprotocols + if ([folderMetadata objectForKey: @"MoreAvailable"]) + [theBuffer appendString: @""]; - [theBuffer appendString: changeBuffer]; [theBuffer appendString: commandsBuffer]; + [theBuffer appendString: changeBuffer]; [theBuffer appendString: @""]; } @@ -1186,21 +1349,42 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSArray *allCollections; NSData *d; - int i, j, defaultInterval, heartbeatInterval, internalInterval; + int i, j, defaultInterval, heartbeatInterval, internalInterval, maxSyncResponseSize; BOOL changeDetected; + changeDetected = NO; + + maxSyncResponseSize = [[SOGoSystemDefaults sharedSystemDefaults] maximumSyncResponseSize]; + // We initialize our output buffer - output = [NSMutableString string]; + output = [[NSMutableString alloc] init]; [output appendString: @""]; [output appendString: @""]; [output appendString: @""]; + + // + // We don't support yet empty Sync requests. See: http://msdn.microsoft.com/en-us/library/ee203280(v=exchg.80).aspx + // We return '13' - see http://msdn.microsoft.com/en-us/library/gg675457(v=exchg.80).aspx + // + if (!theDocumentElement || [[(id)[theDocumentElement getElementsByTagName: @"Partial"] lastObject] textValue]) + { + [output appendString: @"13"]; + [output appendString: @""]; + d = [[output dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; + [theResponse setContent: d]; + return; + } defaults = [SOGoSystemDefaults sharedSystemDefaults]; heartbeatInterval = [[[(id)[theDocumentElement getElementsByTagName: @"HeartbeatInterval"] lastObject] textValue] intValue]; defaultInterval = [defaults maximumSyncInterval]; internalInterval = [defaults internalSyncInterval]; + // If the request doesn't contain "HeartbeatInterval" there is no reason to delay the response. + if (heartbeatInterval == 0) + heartbeatInterval = internalInterval = 1; + // We check to see if our heartbeat interval falls into the supported ranges. if (heartbeatInterval > defaultInterval || heartbeatInterval < 1) { @@ -1217,7 +1401,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. allCollections = (id)[theDocumentElement getElementsByTagName: @"Collection"]; // We enter our loop detection change - for (i = 0; i < (defaultInterval/internalInterval); i++) + for (i = 0; i < (heartbeatInterval/internalInterval); i++) { s = [NSMutableString string]; @@ -1225,31 +1409,46 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { aCollection = [allCollections objectAtIndex: j]; - [self processSyncCollection: aCollection inBuffer: s changeDetected: &changeDetected]; + [self processSyncCollection: aCollection + inBuffer: s + changeDetected: &changeDetected + maxSyncResponseSize: maxSyncResponseSize]; } if (changeDetected) { - NSLog(@"Change detected, we push the content."); + [self logWithFormat: @"Change detected, we push the content."]; break; } + else if (heartbeatInterval > 1) + { + [self logWithFormat: @"Sleeping %d seconds while detecting changes...", internalInterval]; + sleep(internalInterval); + } else { - NSLog(@"Sleeping %d seconds while detecting changes...", internalInterval); - sleep(internalInterval); + break; } } - // We always return the last generated response. - // If we only return , - // iOS powered devices will simply crash. - [output appendString: s]; + // Only send a response if there are changes otherwise send an empty response. + if (changeDetected) + { + // We always return the last generated response. + // If we only return , + // iOS powered devices will simply crash. + [output appendString: s]; - [output appendString: @""]; - - d = [[output dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; + [output appendString: @""]; - [theResponse setContent: d]; + d = [output dataUsingEncoding: NSUTF8StringEncoding]; + d = [d xml2wbxml]; + [theResponse setContent: d]; + } + + // Avoid overloading the autorelease pool here, as Sync command can + // generate fairly large responses. + RELEASE(output); } @end diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index 0d5287a8a..ff9321f92 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -30,12 +30,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "SOGoActiveSyncDispatcher.h" #import +#import #import #import #import #import +#import #import +#import +#import #import #import #import @@ -55,6 +59,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import #import +#import #import #import @@ -89,6 +94,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import #import +#import #import #import @@ -126,6 +132,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @interface SOGoActiveSyncDispatcher (Sync) - (NSMutableDictionary *) _folderMetadataForKey: (NSString *) theFolderKey; +- (void) _setFolderMetadata: (NSDictionary *) theFolderMetadata forKey: (NSString *) theFolderKey; @end @@ -186,7 +193,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (theFilter) { - o = [SOGoCacheGCSObject objectWithName: [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], theCollectionId] inContainer: nil]; + o = [SOGoCacheGCSObject objectWithName: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], theCollectionId] inContainer: nil]; [o setObjectType: ActiveSyncGlobalCacheObject]; [o setTableUrl: [self folderTableURL]]; [o reloadIfNeeded]; @@ -223,7 +230,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Get the GUID of the IMAP folder imapGUIDs = [accountFolder imapFolderGUIDs]; - return [[imapGUIDs allKeysForObject: theIdToTranslate] objectAtIndex: 0]; + //return [[imapGUIDs allKeysForObject: theIdToTranslate] objectAtIndex: 0]; + return [[[imapGUIDs allKeysForObject: [NSString stringWithFormat: @"folder%@", theIdToTranslate]] objectAtIndex: 0] substringFromIndex: 6] ; } return theIdToTranslate; @@ -244,13 +252,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { case ActiveSyncContactFolder: { - collection = [[context activeUser] personalContactsFolderInContext: context]; + collection = [[[[context activeUser] homeFolderInContext: context] lookupName: @"Contacts" inContext: context acquire: NO] lookupName: theCollectionId inContext: context acquire: NO]; + if (!collection || ([collection isKindOfClass: [NSException class]])) + collection = nil; + } break; case ActiveSyncEventFolder: case ActiveSyncTaskFolder: { - collection = [[context activeUser] personalCalendarFolderInContext: context]; + collection = [[[[context activeUser] homeFolderInContext: context] lookupName: @"Calendar" inContext: context acquire: NO] lookupName: theCollectionId inContext: context acquire: NO]; + if (!collection || ([collection isKindOfClass: [NSException class]])) + collection = nil; } break; case ActiveSyncMailFolder: @@ -267,6 +280,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. collection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", theCollectionId] inContext: context acquire: NO]; + if (![(SOGoMailFolder *)collection exists]) + collection = nil; } } @@ -335,27 +350,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSString *key; nameInContainer = [newFolder nameInContainer]; - - // We strip the "folder" prefix - nameInContainer = [nameInContainer substringFromIndex: 6]; - // save new guid into cache accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; - - // update GUID in cache imapGUIDs = [accountFolder imapFolderGUIDs]; + nameInContainer =[imapGUIDs objectForKey: nameInContainer]; - key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], nameInContainer ]; + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], nameInContainer ]; o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; [o setObjectType: ActiveSyncFolderCacheObject]; [o setTableUrl: [self folderTableURL]]; [o reloadIfNeeded]; - nameInContainer =[imapGUIDs objectForKey: nameInContainer]; - - [[o properties ] setObject: nameInContainer forKey: @"GUID"]; + [[o properties ] setObject: [[newFolder nameInContainer] substringFromIndex: 6] forKey: @"displayName"]; [o save]; - nameInContainer = [[NSString stringWithFormat: @"mail/%@", nameInContainer] stringByEscapingURL]; + nameInContainer = [[NSString stringWithFormat: @"mail/%@", [nameInContainer substringFromIndex: 6]] stringByEscapingURL]; } else { @@ -369,7 +377,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. case 15: { SOGoAppointmentFolders *appointmentFolders; - + SOGoCacheGCSObject *o; + NSString *key; + + nameInContainer = nil; + appointmentFolders = [userFolder privateCalendars: @"Calendar" inContext: context]; [appointmentFolders newFolderWithName: displayName nameInContainer: &nameInContainer]; @@ -377,16 +389,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. nameInContainer = [NSString stringWithFormat: @"vevent/%@", nameInContainer]; else nameInContainer = [NSString stringWithFormat: @"vtodo/%@", nameInContainer]; + + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], nameInContainer ]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + [[o properties ] setObject: displayName forKey: @"displayName"]; + [o save]; } break; case 14: { SOGoContactFolders *contactFolders; + SOGoCacheGCSObject *o; + NSString *key; + + nameInContainer = nil; contactFolders = [userFolder privateContacts: @"Contacts" inContext: context]; [contactFolders newFolderWithName: displayName nameInContainer: &nameInContainer]; nameInContainer = [NSString stringWithFormat: @"vcard/%@", nameInContainer]; + + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], nameInContainer ]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + [[o properties ] setObject: displayName forKey: @"displayName"]; + [o save]; } break; default: @@ -428,66 +460,87 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. inResponse: (WOResponse *) theResponse { SOGoMailAccounts *accountsFolder; - SOGoMailFolder *folderToDelete; SOGoUserFolder *userFolder; - id currentFolder; - NSException *error; - NSString *serverId; - + id currentFolder, folderToDelete; + NSString *serverId, *nameInCache, *key, *syncKey; + SOGoCacheGCSObject *o; + NSMutableString *s; + NSData *d; + SOGoMicrosoftActiveSyncFolderType folderType; - + serverId = [[[(id)[theDocumentElement getElementsByTagName: @"ServerId"] lastObject] textValue] realCollectionIdWithFolderType: &folderType]; + nameInCache = serverId; serverId = [self globallyUniqueIDToIMAPFolderName: serverId type: folderType]; - userFolder = [[context activeUser] homeFolderInContext: context]; - accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; - currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; - folderToDelete = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", serverId] - inContext: context - acquire: NO]; - - error = [folderToDelete delete]; - - if (!error) + switch (folderType) { - NSString *syncKey, *key; - SOGoCacheGCSObject *o; - NSMutableString *s; - NSData *d; + case ActiveSyncMailFolder: + { + nameInCache = [NSString stringWithFormat: @"folder%@", nameInCache]; + accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; + currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; + + folderToDelete = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", serverId] + inContext: context + acquire: NO]; + } + break; + case ActiveSyncEventFolder: + case ActiveSyncTaskFolder: + { + SOGoAppointmentFolders *appointmentFolders; - // - // We destroy the cache object - // - key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], [folderToDelete nameInContainer]]; - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setTableUrl: [self folderTableURL]]; - [o destroy]; - - // - // We update the FolderSync's synckey - // - syncKey = [[NSProcessInfo processInfo] globallyUniqueString]; - - [self _setFolderSyncKey: syncKey]; - - s = [NSMutableString string]; - [s appendString: @""]; - [s appendString: @""]; - [s appendString: @""]; - [s appendFormat: @"%d", 1]; - [s appendFormat: @"%@", syncKey]; - [s appendString: @""]; - - d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; - - [theResponse setContent: d]; - } - else - { - [theResponse setStatus: 500]; - [theResponse appendContentString: @"Unable to delete folder."]; + if (folderType == ActiveSyncEventFolder) + nameInCache = [NSString stringWithFormat: @"vevent/%@", serverId]; + else + nameInCache = [NSString stringWithFormat: @"vtodo/%@", serverId]; + + appointmentFolders = [userFolder privateCalendars: @"Calendar" inContext: context]; + + folderToDelete = [appointmentFolders lookupName: [NSString stringWithFormat: @"%@", serverId] + inContext: context + acquire: NO]; + } + break; + default: + { + [theResponse setStatus: 500]; + [theResponse appendContentString: @"Unsupported folder type during creation."]; + return; + } } + + // FIXME: we should handle exception here + [folderToDelete delete]; + + // + // We destroy the cache object + // + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], nameInCache]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setTableUrl: [self folderTableURL]]; + [o destroy]; + + + // + // We update the FolderSync's synckey + // + syncKey = [[NSProcessInfo processInfo] globallyUniqueString]; + + [self _setFolderSyncKey: syncKey]; + + s = [NSMutableString string]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @""]; + [s appendFormat: @"%d", 1]; + [s appendFormat: @"%@", syncKey]; + [s appendString: @""]; + + d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; + [theResponse setContent: d]; } // @@ -496,89 +549,127 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processFolderUpdate: (id ) theDocumentElement inResponse: (WOResponse *) theResponse { - NSString *serverId, *parentId, *displayName; - SOGoMailAccounts *accountsFolder; + NSString *serverId, *parentId, *displayName, *newName, *nameInCache, *syncKey, *key; SOGoUserFolder *userFolder; - SOGoMailFolder *folderToUpdate; + SOGoCacheGCSObject *o; + NSMutableString *s; id currentFolder; - NSException *error; + NSData *d; SOGoMicrosoftActiveSyncFolderType folderType; - int status; serverId = [[[(id)[theDocumentElement getElementsByTagName: @"ServerId"] lastObject] textValue] realCollectionIdWithFolderType: &folderType]; + + nameInCache = [NSString stringWithFormat: @"folder%@", serverId]; + serverId = [self globallyUniqueIDToIMAPFolderName: serverId type: folderType]; parentId = [[(id)[theDocumentElement getElementsByTagName: @"ParentId"] lastObject] textValue]; displayName = [[(id)[theDocumentElement getElementsByTagName: @"DisplayName"] lastObject] textValue]; userFolder = [[context activeUser] homeFolderInContext: context]; - accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; - currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; + + + switch (folderType) + { + case ActiveSyncMailFolder: + { + SOGoMailAccounts *accountsFolder; + SOGoMailFolder *folderToUpdate; + + accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; + currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; - folderToUpdate = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", serverId] - inContext: context - acquire: NO]; + folderToUpdate = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", serverId] + inContext: context + acquire: NO]; - // If parent is 0 or displayname is not changed it is either a rename of a folder in 0 or a move to 0 - if ([parentId isEqualToString: @"0"] || - ([serverId hasSuffix: [NSString stringWithFormat: @"/%@", displayName]] && [parentId isEqualToString: @"0"])) - { - error = [folderToUpdate renameTo: [NSString stringWithFormat: @"/%@", [displayName stringByEncodingImap4FolderName]]]; - } - else - { - parentId = [self globallyUniqueIDToIMAPFolderName: [[parentId stringByUnescapingURL] substringFromIndex: 5] type: folderType]; - error = [folderToUpdate renameTo: [NSString stringWithFormat: @"%@/%@", [parentId stringByEncodingImap4FolderName], - [displayName stringByEncodingImap4FolderName]]]; + // If parent is 0 or displayname is not changed it is either a rename of a folder in 0 or a move to 0 + if ([parentId isEqualToString: @"0"] || + ([serverId hasSuffix: [NSString stringWithFormat: @"/%@", displayName]] && [parentId isEqualToString: @"0"])) + { + newName = [NSString stringWithFormat: @"%@", [displayName stringByEncodingImap4FolderName]]; + + // FIXME: handle exception here + [folderToUpdate renameTo: [NSString stringWithFormat: @"/%@", [displayName stringByEncodingImap4FolderName]]]; + } + else + { + parentId = [self globallyUniqueIDToIMAPFolderName: [[parentId stringByUnescapingURL] substringFromIndex: 5] type: folderType]; + newName = [NSString stringWithFormat: @"%@/%@", [parentId stringByEncodingImap4FolderName], [displayName stringByEncodingImap4FolderName]]; + + // FIXME: handle exception here + [folderToUpdate renameTo: newName]; + } + + + // + // We update our cache + // + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], nameInCache]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + [[o properties ] setObject: newName forKey: @"displayName"]; + [o save]; + } + break; + case ActiveSyncEventFolder: + case ActiveSyncTaskFolder: + { + SOGoAppointmentFolders *appointmentFolders; + SOGoAppointmentFolder *folderToUpdate; + NSString *nameInCache; + + appointmentFolders = [userFolder privateCalendars: @"Calendar" inContext: context]; + + folderToUpdate = [appointmentFolders lookupName: [NSString stringWithFormat: @"%@", serverId] + inContext: context + acquire: NO]; + + // update the cache anyway regardless of any error; if the rename fails next folderSync will to the cleanup + [folderToUpdate renameTo: [NSString stringWithFormat: @"%@", [displayName stringByEncodingImap4FolderName]]]; + + if (folderType == ActiveSyncEventFolder) + nameInCache = [NSString stringWithFormat: @"vevent/%@", serverId]; + else + nameInCache = [NSString stringWithFormat: @"vtodo/%@",serverId]; + + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], nameInCache ]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + [[o properties ] setObject: displayName forKey: @"displayName"]; + [o save]; + } + break; + default: + { + [theResponse setStatus: 500]; + [theResponse appendContentString: @"Unsupported folder type during creation."]; + return; + } } - // Handle new name exist - if (!error) - { - NSString *syncKey, *key; - SOGoCacheGCSObject *o; - NSMutableString *s; - NSData *d; - - // - // We update our cache - // - key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], serverId]; - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; - - key = [NSString stringWithFormat: @"/%@+%@", [context objectForKey: @"DeviceId"], [folderToUpdate nameInContainer]]; - [o changePathTo: key]; + // + // We update the FolderSync's synckey + // + syncKey = [[NSProcessInfo processInfo] globallyUniqueString]; - // - // We update the FolderSync's synckey - // - syncKey = [[NSProcessInfo processInfo] globallyUniqueString]; + [self _setFolderSyncKey: syncKey]; - // See http://msdn.microsoft.com/en-us/library/gg675615(v=exchg.80).aspx - // we return '9' - we force a FolderSync - status = 1; - - [self _setFolderSyncKey: syncKey]; - - s = [NSMutableString string]; - [s appendString: @""]; - [s appendString: @""]; - [s appendString: @""]; - [s appendFormat: @"%d", status]; - [s appendFormat: @"%@", syncKey]; - [s appendString: @""]; + s = [NSMutableString string]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @""]; + [s appendFormat: @"%d", 1]; + [s appendFormat: @"%@", syncKey]; + [s appendString: @""]; + + d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; - d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; - - [theResponse setContent: d]; - } - else - { - [theResponse setStatus: 500]; - [theResponse appendContentString: @"Unable to update folder."]; - } + [theResponse setContent: d]; } @@ -592,21 +683,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processFolderSync: (id ) theDocumentElement inResponse: (WOResponse *) theResponse { - - NSMutableDictionary *metadata; - NSMutableString *s; - NSString *syncKey; + NSString *key, *cKey, *nkey, *name, *serverId, *parentId, *nameInCache, *personalFolderName, *syncKey, *folderType; + NSDictionary *folderMetadata, *imapGUIDs; + NSArray *allFoldersMetadata, *allKeys; + NSMutableDictionary *cachedGUIDs, *metadata; + SOGoMailAccounts *accountsFolder; + SOGoMailAccount *accountFolder; + NSMutableString *s, *commands; + SOGoUserFolder *userFolder; + NSMutableArray *folders; + SoSecurityManager *sm; + SOGoCacheGCSObject *o; + id currentFolder; NSData *d; - - BOOL first_sync; - int status; + int status, command_count, i, type, fi, count; + + BOOL first_sync; + + sm = [SoSecurityManager sharedSecurityManager]; metadata = [self _globalMetadataForDevice]; syncKey = [[(id)[theDocumentElement getElementsByTagName: @"SyncKey"] lastObject] textValue]; s = [NSMutableString string]; first_sync = NO; status = 1; + command_count = 0; + commands = [NSMutableString string]; + + [s appendString: @""]; + [s appendString: @""]; if ([syncKey isEqualToString: @"0"]) { @@ -616,215 +722,326 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. else if (![syncKey isEqualToString: [metadata objectForKey: @"FolderSyncKey"]]) { // Synchronization key mismatch or invalid synchronization key - status = 9; + //NSLog(@"FolderSync syncKey mismatch %@ <> %@", syncKey, metadata); + [s appendFormat: @"9"]; + + d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; + [theResponse setContent: d]; + return; } - [self _setFolderSyncKey: syncKey]; + userFolder = [[context activeUser] homeFolderInContext: context]; + accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; + accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; - [s appendString: @""]; - [s appendString: @""]; - [s appendFormat: @"%d%@", status, syncKey]; - - if (status == 1) - { - SOGoMailAccounts *accountsFolder; - SOGoMailAccount *accountFolder; - SOGoUserFolder *userFolder; - id currentFolder; - - NSString *key, *cKey, *nkey, *name, *serverId, *parentId; - NSDictionary *folderMetadata, *imapGUIDs; - NSArray *allFoldersMetadata, *allKeys; - NSMutableDictionary *cachedGUIDs; - NSMutableString *commands; - SOGoCacheGCSObject *o; - - int i, type, command_count; - - userFolder = [[context activeUser] homeFolderInContext: context]; - accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; - accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; - - allFoldersMetadata = [accountFolder allFoldersMetadata]; + allFoldersMetadata = [accountFolder allFoldersMetadata]; - // Get GUIDs of folder (IMAP) - // e.g. {INBOX = "sogo_73c_192bd57b_d8" - imapGUIDs = [accountFolder imapFolderGUIDs]; + // Get GUIDs of folder (IMAP) + // e.g. {folderINBOX = folder6b93c528176f1151c7260000aef6df92} + imapGUIDs = [accountFolder imapFolderGUIDs]; - cachedGUIDs = [NSMutableDictionary dictionary]; + cachedGUIDs = [NSMutableDictionary dictionary]; - // No need to read cached folder infos during first sync. Otherwise, pull it from the database. - // e.g. {"sogo_73c_192bd57b_d8" = INBOX} - guid = foldername for easy reverse lookup with imapGUIDs - if (!first_sync) - { - NSArray *foldersInCache; - NSString *folderName; + // No need to read cached folder infos during first sync. Otherwise, pull it from the database. + // e.g. {folder6b93c528176f1151c7260000aef6df92 = folderINBOX} - guid = foldername for easy reverse lookup with imapGUIDs + if (!first_sync) + { + NSArray *foldersInCache; - // get the list of folder stored in cache - key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], @"0"]; - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setObjectType: ActiveSyncFolderCacheObject]; - [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; - foldersInCache = [o folderList: [context objectForKey: @"DeviceId"] newerThanVersion: -1]; - - // get guids of folders stored in cache - for (i = 0; i < [foldersInCache count]; i++) - { - folderName = [foldersInCache objectAtIndex: i]; - key = [folderName substringFromIndex: 1]; - - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setObjectType: ActiveSyncFolderCacheObject]; - [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; - - if ([[o properties ] objectForKey: @"GUID"]) - [cachedGUIDs setObject: [key substringFromIndex: [key rangeOfString: @"+"].location+7] - forKey: [[o properties] objectForKey: @"GUID"]]; - } - } + o = [SOGoCacheGCSObject objectWithName: @"0" inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: folderTableURL]; + + foldersInCache = [o cacheEntriesForDeviceId: [context objectForKey: @"DeviceId"] newerThanVersion: -1]; + + // get guids of folders stored in cache + for (i = 0; i < [foldersInCache count]; i++) + { + key = [[foldersInCache objectAtIndex: i] substringFromIndex: 1]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + + // When the GUID entry exists the name of the entry has to be changed to new name + if ([[o properties] objectForKey: @"GUID"]) + { + //NSLog(@"Old cacheEntry: %@ displayName: %@ GUID: %@", key, [[o properties] objectForKey: @"displayName"], [[o properties] objectForKey: @"GUID"]); + key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [[o properties] objectForKey: @"GUID"]]; + //NSLog(@"New cacheEntry: %@", key); + [[o properties] removeObjectForKey: @"GUID"]; + [[o properties ] setObject: @"updateMe" forKey: @"displayName"]; + [o save]; + [o changePathTo: [NSString stringWithFormat: @"%@", key]]; + } + + // no dispalay Name + if (![[o properties] objectForKey: @"displayName"]) + continue; + + if ([key rangeOfString: @"+folder" options: NSCaseInsensitiveSearch].location != NSNotFound) + [cachedGUIDs setObject: [NSString stringWithFormat: @"folder%@", [[o properties] objectForKey: @"displayName"]] // e.g. CDB648DDBC5040F8AC90792383DBBBAA+folderINBOX + forKey: [key substringFromIndex: [key rangeOfString: @"+"].location+1]]; + else + [cachedGUIDs setObject: [key substringFromIndex: [key rangeOfString: @"+"].location+1] // e.g. CDB648DDBC5040F8AC90792383DBBBAA+vcard/personal + forKey: [key substringFromIndex: [key rangeOfString: @"+"].location+1]]; + } + } - // Handle folders that have been deleted over IMAP - command_count = 0; - commands = [NSMutableString string]; - allKeys = [cachedGUIDs allKeys]; + // Handle folders that have been deleted on server + allKeys = [cachedGUIDs allKeys]; - for (i = 0; i < [allKeys count]; i++) - { - cKey = [allKeys objectAtIndex: i]; + for (i = 0; i < [allKeys count]; i++) + { + cKey = [allKeys objectAtIndex: i]; - if (![imapGUIDs allKeysForObject: cKey]) - { - // Destroy folders cache content to avoid stale data if a new folder gets created with the same name - key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [cachedGUIDs objectForKey: cKey]]; - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setObjectType: ActiveSyncFolderCacheObject]; - [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; - - // Only send a delete command if GUID is found - if ([[o properties] objectForKey: @"GUID"]) + // if a cache entry is not found in imapGUIDs its either an imap which has been deleted or its an other folder type which can be checked via lookupName. + if (![imapGUIDs allKeysForObject: cKey]) + { + // Destroy folders cache content to avoid stale data if a new folder gets created with the same name + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], cKey]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + + if ([cKey hasPrefix: @"folder"] || [cKey isEqualToString:@"(null)"]) + { + [commands appendFormat: @"%@", [[NSString stringWithFormat: @"mail/%@", [cKey substringFromIndex: 6]] stringByEscapingURL]] ; + command_count++; + + [o destroy]; + } + else + { + if ([cKey rangeOfString: @"vevent" options: NSCaseInsensitiveSearch].location != NSNotFound || + [cKey rangeOfString: @"vtodo" options: NSCaseInsensitiveSearch].location != NSNotFound) + folderType = @"Calendar"; + else + folderType = @"Contacts"; + + if ([ cKey rangeOfString: @"/"].location != NSNotFound) + currentFolder = [[[[context activeUser] homeFolderInContext: context] lookupName: folderType inContext: context acquire: NO] + lookupName: [cKey substringFromIndex: [cKey rangeOfString: @"/"].location+1] inContext: context acquire: NO]; + + // remove the folder from device if it doesn't exists or it has not the proper permissions + if (!currentFolder || + [sm validatePermission: SoPerm_DeleteObjects + onObject: currentFolder + inContext: context] || + [sm validatePermission: SoPerm_AddDocumentsImagesAndFiles + onObject: currentFolder + inContext: context]) { - [commands appendFormat: @"%@", [[NSString stringWithFormat: @"mail/%@", [[o properties ] objectForKey: @"GUID"]] stringByEscapingURL] ]; + [commands appendFormat: @"%@", [cKey stringByEscapingURL] ]; command_count++; - } - - [o destroy]; - } - } - - // Handle addition and changes - for (i = 0; i < [allFoldersMetadata count]; i++) - { - folderMetadata = [allFoldersMetadata objectAtIndex: i]; - - // No GUID -> no sync - if (!([imapGUIDs objectForKey: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]])) - continue; - - serverId = [NSString stringWithFormat: @"mail/%@", [imapGUIDs objectForKey: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]]]; - name = [folderMetadata objectForKey: @"displayName"]; - - if ([name hasPrefix: @"/"]) - name = [name substringFromIndex: 1]; - - if ([name hasSuffix: @"/"]) - name = [name substringToIndex: [name length]-1]; - - type = [[folderMetadata objectForKey: @"type"] activeSyncFolderType]; - parentId = @"0"; - - if ([folderMetadata objectForKey: @"parent"]) - { - parentId = [NSString stringWithFormat: @"mail/%@", [imapGUIDs objectForKey: [[folderMetadata objectForKey: @"parent"] substringFromIndex: 1]]]; - name = [[name pathComponents] lastObject]; - } - - // Decide between add and change - if ([cachedGUIDs objectForKey: [imapGUIDs objectForKey: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]]]) - { - // Search GUID to check name change in cache (diff between IMAP and cache) - if ((![[[folderMetadata objectForKey: @"path"] substringFromIndex: 1] isEqualToString: [imapGUIDs objectForKey: [cachedGUIDs objectForKey: - [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]]]])) - { - key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [cachedGUIDs objectForKey: - [imapGUIDs objectForKey: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]]]]; - nkey = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [[folderMetadata objectForKey: @"path"] substringFromIndex: 1] ]; - - if (![key isEqualToString: nkey]) - { - [commands appendFormat: @"%@%@%d%@", - [serverId stringByEscapingURL], - [parentId stringByEscapingURL], - type, - [name activeSyncRepresentationInContext: context]]; - - - // Change path in cache - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setObjectType: ActiveSyncFolderCacheObject]; - [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; - [o changePathTo: [NSString stringWithFormat: @"/%@", nkey]]; // ?? why is '/' prefix needed - problem in changePathTo? - - command_count++; - } + [o destroy]; } } - else - { - [commands appendFormat: @"%@%@%d%@", + } + } + + // Handle addition and changes + for (i = 0; i < [allFoldersMetadata count]; i++) + { + folderMetadata = [allFoldersMetadata objectAtIndex: i]; + + nameInCache = [NSString stringWithFormat: @"folder%@", [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]]; + + // we have no guid - ignore the folder + if (![imapGUIDs objectForKey: nameInCache]) + continue; + + serverId = [NSString stringWithFormat: @"mail/%@", [[imapGUIDs objectForKey: nameInCache] substringFromIndex: 6]]; + name = [folderMetadata objectForKey: @"displayName"]; + + if ([name hasPrefix: @"/"]) + name = [name substringFromIndex: 1]; + + if ([name hasSuffix: @"/"]) + name = [name substringToIndex: [name length]-1]; + + type = [[folderMetadata objectForKey: @"type"] activeSyncFolderType]; + parentId = @"0"; + + if ([folderMetadata objectForKey: @"parent"]) + { + parentId = [NSString stringWithFormat: @"mail/%@", [[imapGUIDs objectForKey: [NSString stringWithFormat: @"folder%@", [[folderMetadata objectForKey: @"parent"] substringFromIndex: 1]]] substringFromIndex: 6]]; + name = [[name pathComponents] lastObject]; + } + + // Decide between add and change + if ([cachedGUIDs objectForKey: [imapGUIDs objectForKey: nameInCache]]) + { + // Search GUID to check name change in cache (diff between IMAP and cache) + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], [cachedGUIDs objectForKey: [imapGUIDs objectForKey: nameInCache ]]]; + nkey = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [[folderMetadata objectForKey: @"path"] substringFromIndex: 1] ]; + + if (![key isEqualToString: nkey]) + { + [commands appendFormat: @"%@%@%@%d", + [serverId stringByEscapingURL], + [parentId stringByEscapingURL], + [name activeSyncRepresentationInContext: context], type]; + + // Change path in cache + o = [SOGoCacheGCSObject objectWithName: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], [imapGUIDs objectForKey: nameInCache ]] inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + + [[o properties ] setObject: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1] forKey: @"displayName"]; + [o save]; + + command_count++; + } + } + else + { + [commands appendFormat: @"%@%@%@%d", [serverId stringByEscapingURL], [parentId stringByEscapingURL], - type, - [name activeSyncRepresentationInContext: context]]; + [name activeSyncRepresentationInContext: context], type]; - // Store folder's GUID in cache - key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]]; - o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; - [o setObjectType: ActiveSyncFolderCacheObject]; - [o setTableUrl: [self folderTableURL]]; - [o reloadIfNeeded]; + // Store folder's displayName in cache + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], [imapGUIDs objectForKey: nameInCache ]]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; - [[o properties ] setObject: [imapGUIDs objectForKey: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]] forKey: @"GUID"]; - [o save]; - - command_count++; - } - } - - if (first_sync) - [s appendFormat: @"%d", command_count+3]; - else - [s appendFormat: @"%d", command_count]; - - if (command_count > 0) - [s appendFormat: @"%@", commands]; - - if (first_sync) - { - // We add the personal calendar - events - // FIXME: add all calendars - currentFolder = [[context activeUser] personalCalendarFolderInContext: context]; - name = [NSString stringWithFormat: @"vevent/%@", [currentFolder nameInContainer]]; - [s appendFormat: @"%@%@%d%@", name, @"0", 8, [[currentFolder displayName] activeSyncRepresentationInContext: context]]; + [[o properties ] setObject: [[folderMetadata objectForKey: @"path"] substringFromIndex: 1] forKey: @"displayName"]; - // We add the personal calendar - tasks - // FIXME: add all calendars - currentFolder = [[context activeUser] personalCalendarFolderInContext: context]; - name = [NSString stringWithFormat: @"vtodo/%@", [currentFolder nameInContainer]]; - [s appendFormat: @"%@%@%d%@", name, @"0", 7, [[currentFolder displayName] activeSyncRepresentationInContext: context]]; - - // We add the personal address book - // FIXME: add all address books - currentFolder = [[context activeUser] personalContactsFolderInContext: context]; - name = [NSString stringWithFormat: @"vcard/%@", [currentFolder nameInContainer]]; - [s appendFormat: @"%@%@%d%@", name, @"0", 9, [[currentFolder displayName] activeSyncRepresentationInContext: context]]; - } + // clean cache content to avoid stale data + [[o properties] removeObjectForKey: @"SyncKey"]; + [[o properties] removeObjectForKey: @"SyncCache"]; + [[o properties] removeObjectForKey: @"DateCache"]; + [[o properties] removeObjectForKey: @"MoreAvailable"]; + [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [o save]; + + command_count++; + } } + + personalFolderName = [[[context activeUser] personalCalendarFolderInContext: context] nameInContainer]; + folders = [[[[[context activeUser] homeFolderInContext: context] lookupName: @"Calendar" inContext: context acquire: NO] subFolders] mutableCopy]; + [folders addObjectsFromArray: [[[[context activeUser] homeFolderInContext: context] lookupName: @"Contacts" inContext: context acquire: NO] subFolders]]; + + // Inside this loop we remove all the folder without write/delete permissions + count = [folders count]-1; + for (; count >= 0; count--) + { + if ([sm validatePermission: SoPerm_DeleteObjects + onObject: [folders objectAtIndex: count] + inContext: context] || + [sm validatePermission: SoPerm_AddDocumentsImagesAndFiles + onObject: [folders objectAtIndex: count] + inContext: context]) + { + [folders removeObjectAtIndex: count]; + } + } + + count = [folders count]-1; + NSString *operation; + + for (fi = 0; fi <= count ; fi++) + { + if ([[folders objectAtIndex:fi] isKindOfClass: [SOGoAppointmentFolder class]]) + name = [NSString stringWithFormat: @"vevent/%@", [[folders objectAtIndex:fi] nameInContainer]]; + else + name = [NSString stringWithFormat: @"vcard/%@", [[folders objectAtIndex:fi] nameInContainer]]; + + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], name]; + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + + // Decide between add and change + if (![[o properties ] objectForKey: @"displayName"] || first_sync) + operation = @"Add"; + else if (![[[o properties ] objectForKey: @"displayName"] isEqualToString: [[folders objectAtIndex:fi] displayName]]) + operation = @"Update"; + else + operation = nil; + + if (operation) + { + if ([[folders objectAtIndex:fi] isKindOfClass: [SOGoAppointmentFolder class]]) + { + type = ([[[folders objectAtIndex:fi] nameInContainer] isEqualToString: personalFolderName] ? 8 : 13); + [commands appendFormat: @"<%@>%@%@%@%d", operation, + [name stringByEscapingURL], @"0", [[[folders objectAtIndex:fi] displayName] activeSyncRepresentationInContext: context], type, operation]; + + command_count++; + + [[o properties ] setObject: [[folders objectAtIndex:fi] displayName] forKey: @"displayName"]; + [o save]; + + name = [NSString stringWithFormat: @"vtodo/%@", [[folders objectAtIndex:fi] nameInContainer]]; + type = ([[[folders objectAtIndex:fi] nameInContainer] isEqualToString: personalFolderName] ? 7 : 15); + [commands appendFormat: @"<%@>%@%@%@%d", operation, + [name stringByEscapingURL], @"0", [[[folders objectAtIndex:fi] displayName] activeSyncRepresentationInContext: context], type, operation]; + + command_count++; + key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], name]; + + o = [SOGoCacheGCSObject objectWithName: key inContainer: nil]; + [o setObjectType: ActiveSyncFolderCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + [[o properties ] setObject: [[folders objectAtIndex:fi] displayName] forKey: @"displayName"]; + + if ([operation isEqualToString: @"Add"]) + { + // clean cache content to avoid stale data + [[o properties] removeObjectForKey: @"SyncKey"]; + [[o properties] removeObjectForKey: @"SyncCache"]; + [[o properties] removeObjectForKey: @"DateCache"]; + [[o properties] removeObjectForKey: @"MoreAvailable"]; + [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + } + + [o save]; + } + else if ([[folders objectAtIndex:fi] isKindOfClass: [SOGoContactGCSFolder class]]) + { + type = ([[[folders objectAtIndex:fi] nameInContainer] isEqualToString: personalFolderName] ? 9 : 14); + [commands appendFormat: @"<%@>%@%@%@%d", operation, + [name stringByEscapingURL], @"0", [[[folders objectAtIndex:fi] displayName] activeSyncRepresentationInContext: context], type, operation]; + + command_count++; + + [[o properties ] setObject: [[folders objectAtIndex:fi] displayName] forKey: @"displayName"]; + + if ([operation isEqualToString: @"Add"]) + { + // clean cache content to avoid stale data + [[o properties] removeObjectForKey: @"SyncKey"]; + [[o properties] removeObjectForKey: @"SyncCache"]; + [[o properties] removeObjectForKey: @"DateCache"]; + [[o properties] removeObjectForKey: @"MoreAvailable"]; + [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; + } + + [o save]; + } + } + } + - [s appendString: @""]; + // set a new syncKey if there are folder changes + if (command_count > 0) + { + syncKey = [[NSProcessInfo processInfo] globallyUniqueString]; + [self _setFolderSyncKey: syncKey]; + } + + + [s appendFormat: @"%d", status]; + [s appendFormat: @"%@%d%@", syncKey, command_count, commands]; d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; @@ -906,7 +1123,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processGetItemEstimate: (id ) theDocumentElement inResponse: (WOResponse *) theResponse { - NSString *collectionId, *realCollectionId; + NSString *collectionId, *realCollectionId, *nameInCache; id currentCollection; NSMutableString *s; NSData *d; @@ -920,7 +1137,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. collectionId = [[(id)[theDocumentElement getElementsByTagName: @"CollectionId"] lastObject] textValue]; realCollectionId = [collectionId realCollectionIdWithFolderType: &folderType]; + + if (folderType == ActiveSyncMailFolder) + nameInCache = [NSString stringWithFormat: @"folder%@", realCollectionId]; + else + nameInCache = collectionId; + realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType]; + currentCollection = [self collectionFromId: realCollectionId type: folderType]; // @@ -955,7 +1179,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. count = [uids count]; // Add the number of UIDs expected to "soft delete" - count += [self _softDeleteCountWithFilter: filter collectionId: realCollectionId]; + count += [self _softDeleteCountWithFilter: filter collectionId: nameInCache]; } else @@ -993,71 +1217,136 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { NSString *fileReference, *realCollectionId; NSMutableString *s; + NSArray *fetchRequests; + id aFetch; + int i; SOGoMicrosoftActiveSyncFolderType folderType; - fileReference = [[[(id)[theDocumentElement getElementsByTagName: @"FileReference"] lastObject] textValue] stringByUnescapingURL]; + s = [NSMutableString string]; - realCollectionId = [fileReference realCollectionIdWithFolderType: &folderType]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @"1"]; + [s appendString: @""]; + + fetchRequests = (id)[theDocumentElement getElementsByTagName: @"Fetch"]; - if (folderType == ActiveSyncMailFolder) + if ([fetchRequests count]) { - id currentFolder, currentCollection, currentBodyPart; - NSString *folderName, *messageName, *pathToPart; - SOGoMailAccounts *accountsFolder; - SOGoUserFolder *userFolder; - SOGoMailObject *mailObject; + NSMutableData *bytes, *parts; + NSMutableArray *partLength; NSData *d; - NSRange r1, r2; + bytes = [NSMutableData data]; + parts = [NSMutableData data]; + partLength = [NSMutableArray array]; - r1 = [realCollectionId rangeOfString: @"/"]; - r2 = [realCollectionId rangeOfString: @"/" options: 0 range: NSMakeRange(NSMaxRange(r1)+1, [realCollectionId length]-NSMaxRange(r1)-1)]; + for (i = 0; i < [fetchRequests count]; i++) + { + aFetch = [fetchRequests objectAtIndex: i]; + fileReference = [[[(id)[aFetch getElementsByTagName: @"FileReference"] lastObject] textValue] stringByUnescapingURL]; + realCollectionId = [fileReference realCollectionIdWithFolderType: &folderType]; + + if (folderType == ActiveSyncMailFolder) + { + id currentFolder, currentCollection, currentBodyPart; + NSString *folderName, *messageName, *pathToPart; + SOGoMailAccounts *accountsFolder; + SOGoUserFolder *userFolder; + SOGoMailObject *mailObject; + + NSRange r1, r2; + + r1 = [realCollectionId rangeOfString: @"/"]; + r2 = [realCollectionId rangeOfString: @"/" options: 0 range: NSMakeRange(NSMaxRange(r1)+1, [realCollectionId length]-NSMaxRange(r1)-1)]; - folderName = [realCollectionId substringToIndex: r1.location]; - messageName = [realCollectionId substringWithRange: NSMakeRange(NSMaxRange(r1), r2.location-r1.location-1)]; - pathToPart = [realCollectionId substringFromIndex: r2.location+1]; - - userFolder = [[context activeUser] homeFolderInContext: context]; - accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; - currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; + folderName = [realCollectionId substringToIndex: r1.location]; + messageName = [realCollectionId substringWithRange: NSMakeRange(NSMaxRange(r1), r2.location-r1.location-1)]; + pathToPart = [realCollectionId substringFromIndex: r2.location+1]; - currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", folderName] - inContext: context - acquire: NO]; - - mailObject = [currentCollection lookupName: messageName inContext: context acquire: NO]; - currentBodyPart = [mailObject lookupImap4BodyPartKey: pathToPart inContext: context]; + userFolder = [[context activeUser] homeFolderInContext: context]; + accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; + currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; + currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", folderName] + inContext: context + acquire: NO]; - s = [NSMutableString string]; - [s appendString: @""]; - [s appendString: @""]; - [s appendString: @""]; - [s appendString: @"1"]; - [s appendString: @""]; + mailObject = [currentCollection lookupName: messageName inContext: context acquire: NO]; + currentBodyPart = [mailObject lookupImap4BodyPartKey: pathToPart inContext: context]; - [s appendString: @""]; - [s appendString: @"1"]; - [s appendFormat: @"%@", [fileReference stringByEscapingURL]]; - [s appendString: @""]; + [s appendString: @""]; + [s appendString: @"1"]; + [s appendFormat: @"%@", [fileReference stringByEscapingURL]]; + [s appendString: @""]; - [s appendFormat: @"%@/%@", [[currentBodyPart partInfo] objectForKey: @"type"], [[currentBodyPart partInfo] objectForKey: @"subtype"]]; - [s appendFormat: @"%@", [[currentBodyPart fetchBLOB] activeSyncRepresentationInContext: context]]; + [s appendFormat: @"%@/%@", [[currentBodyPart partInfo] objectForKey: @"type"], [[currentBodyPart partInfo] objectForKey: @"subtype"]]; - [s appendString: @""]; - [s appendString: @""]; + if ([[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.multipart"]) + { + [s appendFormat: @"%d", i+1]; + [partLength addObject: [NSNumber numberWithInteger: [[currentBodyPart fetchBLOB] length]]]; + [parts appendData:[currentBodyPart fetchBLOB]]; + } + else + { + [s appendFormat: @"0-%d", [[[currentBodyPart fetchBLOB] activeSyncRepresentationInContext: context] length]-1]; + [s appendFormat: @"%@", [[currentBodyPart fetchBLOB] activeSyncRepresentationInContext: context]]; + } + [s appendString: @""]; + [s appendString: @""]; + } + else + { + [theResponse setStatus: 500]; + return; + } + } [s appendString: @""]; [s appendString: @""]; - + d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; - [theResponse setContent: d]; - } - else - { - [theResponse setStatus: 500]; + + if ([[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.multipart"]) + { + uint32_t PartCount; + uint32_t Offset; + uint32_t Len; + + // 2.2.2.9.1.1 - MultiPartResponse -- http://msdn.microsoft.com/en-us/library/jj663270%28v=exchg.80%29.aspx + PartCount = [partLength count] + 1; + Offset = ((PartCount) * 2) * 4 + 4; + Len = [d length]; + + [bytes appendBytes: &PartCount length: 4]; + [bytes appendBytes: &Offset length: 4]; + [bytes appendBytes: &Len length: 4]; + + // 2.2.2.9.1.1.1 - PartMetaData -- http://msdn.microsoft.com/en-us/library/jj663267%28v=exchg.80%29.aspx + for (i = 0; i < [fetchRequests count]; i++) + { + Offset = Offset + Len; + Len = [[partLength objectAtIndex:i] intValue]; + [bytes appendBytes: &Offset length: 4]; + [bytes appendBytes: &Len length: 4]; + } + + // First part - webxml + [bytes appendData: d]; + + // Subsequent parts - requested data + [bytes appendData: parts]; + + [theResponse setContent: bytes]; + } + else + { + [theResponse setContent: d]; + } } } @@ -1170,7 +1459,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. participationStatus = @"DECLINED"; [appointmentObject changeParticipationStatus: participationStatus - withDelegate: nil]; + withDelegate: nil + alarm: nil]; [s appendString: @""]; [s appendString: @""]; @@ -1207,14 +1497,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processMoveItems: (id ) theDocumentElement inResponse: (WOResponse *) theResponse { - NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId; + NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId, *nameInCache, *currentFolder; + NSMutableDictionary *folderMetadata, *prevSuccessfulMoveItemsOps, *newSuccessfulMoveItemsOps; SOGoMicrosoftActiveSyncFolderType srcFolderType, dstFolderType; id aMoveOperation; NSArray *moveOperations; + SoSecurityManager *sm; NSMutableString *s; NSData *d; int i; + currentFolder = nil; + moveOperations = (id)[theDocumentElement getElementsByTagName: @"Move"]; s = [NSMutableString string]; @@ -1230,11 +1524,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. srcMessageId = [[(id)[aMoveOperation getElementsByTagName: @"SrcMsgId"] lastObject] textValue]; srcFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] realCollectionIdWithFolderType: &srcFolderType]; dstFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] realCollectionIdWithFolderType: &dstFolderType]; + + if (srcFolderType == ActiveSyncMailFolder) + nameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]]; + else + nameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL]; + + if (![nameInCache isEqualToString: currentFolder]) + { + folderMetadata = [self _folderMetadataForKey: nameInCache]; + prevSuccessfulMoveItemsOps = [folderMetadata objectForKey: @"SuccessfulMoveItemsOps"]; + newSuccessfulMoveItemsOps = [NSMutableDictionary dictionary] ; + currentFolder = nameInCache; + } [s appendString: @""]; - // FIXME - we should support moving events between calendars, for example, or - // or contacts between address books. if (srcFolderType == ActiveSyncMailFolder && dstFolderType == ActiveSyncMailFolder) { NGImap4Client *client; @@ -1274,8 +1579,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (!dstMessageId) { - // FIXME: should we return 1 or 2 here? - [s appendFormat: @"%d", 2]; + // Our destination message ID doesn't exist OR even our source message ID doesn't. + // This can happen if you Move items from your EAS client and immediately closes it + // before the server had the time to receive or process the query. Then, if that message + // is moved away by an other client behing the EAS' client back, it obvisouly won't find it. + // The issue the "result" will still be a success, but in fact, it's a failure. Cyrus generates + // this kind of query/response for an 'unkknown' message UID (696969) when trying to copy it + // over to the folder "Trash". + // + // 3 uid copy 696969 "Trash" + // 3 OK Completed + // + // See http://msdn.microsoft.com/en-us/library/gg651088(v=exchg.80).aspx for Status response codes. + // + if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId]) + { + // Previous move failed operation but we can recover the dstMessageId from previous request + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%@", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId]]; + [s appendFormat: @"%d", 3]; + [newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId]; + } + else + { + [s appendFormat: @"%d", 1]; + } } else { @@ -1304,18 +1632,92 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [s appendFormat: @"%@", srcMessageId]; [s appendFormat: @"%@", dstMessageId]; [s appendFormat: @"%d", 3]; + + // Save dstMessageId in cache - it will help to recover if the request fails before the response can be sent to client + [newSuccessfulMoveItemsOps setObject: dstMessageId forKey: srcMessageId]; } } else { - // Non-mail move operations - unsupported for now. - [s appendFormat: @"%d", 1]; + id srcCollection, dstCollection, srcSogoObject, dstSogoObject; + NSArray *elements; + NSString *newUID; + NSException *ex; + + unsigned int count, max; + + srcCollection = [self collectionFromId: srcFolderId type: srcFolderType]; + dstCollection = [self collectionFromId: dstFolderId type: srcFolderType]; + + srcSogoObject = [srcCollection lookupName: [srcMessageId sanitizedServerIdWithType: srcFolderType] + inContext: context + acquire: NO]; + + sm = [SoSecurityManager sharedSecurityManager]; + if (![sm validatePermission: SoPerm_DeleteObjects + onObject: srcCollection + inContext: context]) + { + if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles + onObject: dstCollection + inContext: context]) + { + newUID = [srcSogoObject globallyUniqueObjectId]; + dstSogoObject = [[SOGoAppointmentObject alloc] initWithName: [newUID sanitizedServerIdWithType: srcFolderType] + inContainer: dstCollection]; + elements = [[srcSogoObject calendar: NO secure: NO] allObjects]; + max = [elements count]; + for (count = 0; count < max; count++) + [[elements objectAtIndex: count] setUid: newUID]; + + ex = [dstSogoObject saveCalendar: [srcSogoObject calendar: NO secure: NO]]; + if (!ex) + { + ex = [srcSogoObject delete]; + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%@", newUID]; + [s appendFormat: @"%d", 3]; + + // Save dstMessageId in cache - it will help to recover if the request fails before the response can be sent to client + [newSuccessfulMoveItemsOps setObject: newUID forKey: srcMessageId]; + } + else + { + if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId]) + { + // Move failed but we can recover the dstMessageId from previous request + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%@", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] ]; + [s appendFormat: @"%d", 3]; + [newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId]; + } + else + { + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%d", 1]; + } + } + } + else + { + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%d", 2]; + } + } + else + { + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%d", 1]; + } } [s appendString: @""]; - } + [folderMetadata removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [folderMetadata setObject: newSuccessfulMoveItemsOps forKey: @"SuccessfulMoveItemsOps"]; + [self _setFolderMetadata: folderMetadata forKey: nameInCache]; + } [s appendString: @""]; @@ -1404,30 +1806,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // We build the list of folders to "ping". When the payload is empty, we use the list // of "cached" folders. - allCollections = (id)[theDocumentElement getElementsByTagName: @"Folders"]; + allCollections = (id)[theDocumentElement getElementsByTagName: @"Folder"]; allFoldersID = [NSMutableArray array]; if (![allCollections count]) { - SOGoMailAccounts *accountsFolder; - SOGoMailAccount *accountFolder; - SOGoUserFolder *userFolder; - NSArray *allValues; + // We received an empty Ping request. Return status '3' to ask client to resend the request with complete body. + s = [NSMutableString string]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @"3"]; + [s appendString: @""]; - userFolder = [[context activeUser] homeFolderInContext: context]; - accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; - accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; + d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml]; - allValues = [[accountFolder imapFolderGUIDs] allValues]; - - for (i = 0; i < [allValues count]; i++) - [allFoldersID addObject: [NSString stringWithFormat: @"mail/%@", [allValues objectAtIndex: i]]]; + [theResponse setContent: d]; - - // FIXME: handle multiple GCS collecitons - [allFoldersID addObject: @"vcard/personal"]; - [allFoldersID addObject: @"vevent/personal"]; - [allFoldersID addObject: @"vtodo/personal"]; + return; } else { @@ -1449,26 +1845,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. collectionId = [allFoldersID objectAtIndex: j]; realCollectionId = [collectionId realCollectionIdWithFolderType: &folderType]; realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType]; + + if (folderType == ActiveSyncMailFolder) + folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"folder%@", [[collectionId stringByUnescapingURL] substringFromIndex:5]]]; + else + folderMetadata = [self _folderMetadataForKey: [collectionId stringByUnescapingURL]]; + collection = [self collectionFromId: realCollectionId type: folderType]; - - switch (folderType) - { - case ActiveSyncContactFolder: - folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"vcard/%@", [collection nameInContainer]]]; - break; - case ActiveSyncEventFolder: - folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"vevent/%@", [collection nameInContainer]]]; - break; - case ActiveSyncTaskFolder: - folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"vtodo/%@", [collection nameInContainer]]]; - break; - default: - folderMetadata = [self _folderMetadataForKey: [collection nameInContainer]]; - } + + // If collection doesn't exist skip it - next foldersync will do the cleanup + if (!collection) + continue; syncKey = [folderMetadata objectForKey: @"SyncKey"]; - if (![syncKey isEqualToString: [collection davCollectionTag]]) + if (syncKey && ![syncKey isEqualToString: [collection davCollectionTag]]) { [foldersWithChanges addObject: collectionId]; } @@ -1476,13 +1867,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if ([foldersWithChanges count]) { - NSLog(@"Change detected, we push the content."); + [self logWithFormat: @"Change detected, we push the content."]; status = 2; break; } else { - NSLog(@"Sleeping %d seconds while detecting changes...", internalInterval); + [self logWithFormat: @"Sleeping %d seconds while detecting changes...", internalInterval]; sleep(internalInterval); } } @@ -1829,6 +2220,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NGMimeMessage *message; NSException *error; NSData *data; + NGMutableHashMap *map; + NGMimeMessage *messageToSend; + NGMimeMessageGenerator *generator; + NSDictionary *identity; + NSString *fullName, *email; // We get the mail's data data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding]; @@ -1837,6 +2233,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. parser = [[NGMimeMessageParser alloc] init]; message = [parser parsePartFromData: data]; RELEASE(parser); + + map = [NGHashMap hashMapWithDictionary: [message headers]]; + + identity = [[context activeUser] primaryIdentity]; + + fullName = [identity objectForKey: @"fullName"]; + email = [identity objectForKey: @"email"]; + if ([fullName length]) + [map setObject: [NSString stringWithFormat: @"%@ <%@>", fullName, email] forKey: @"from"]; + else + [map setObject: email forKey: @"from"]; + + messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease]; + + [messageToSend setBody: [message body]]; + + generator = [[[NGMimeMessageGenerator alloc] init] autorelease]; + data = [generator generateMimeFromPart: messageToSend]; error = [self _sendMail: data recipients: [message allRecipients] @@ -1965,6 +2379,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSException *error; id body, bodyFromSmartForward; + NSString *fullName, *email; + NSDictionary *identity; userFolder = [[context activeUser] homeFolderInContext: context]; accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; @@ -1988,6 +2404,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. map = [NGHashMap hashMapWithDictionary: [messageFromSmartForward headers]]; [map setObject: @"multipart/mixed" forKey: @"content-type"]; + identity = [[context activeUser] primaryIdentity]; + + fullName = [identity objectForKey: @"fullName"]; + email = [identity objectForKey: @"email"]; + if ([fullName length]) + [map setObject: [NSString stringWithFormat: @"%@ <%@>", fullName, email] forKey: @"from"]; + else + [map setObject: email forKey: @"from"]; + messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease]; body = [[[NGMimeMultipartBody alloc] initWithPart: messageToSend] autorelease]; @@ -2092,21 +2517,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. context: (id) theContext { id documentElement; + NSAutoreleasePool *pool; id builder, dom; SEL aSelector; NSString *cmdName, *deviceId; NSData *d; + pool = [[NSAutoreleasePool alloc] init]; + ASSIGN(context, theContext); - + // Get the device ID, device type and "stash" them deviceId = [[theRequest uri] deviceId]; [context setObject: deviceId forKey: @"DeviceId"]; [context setObject: [[theRequest uri] deviceType] forKey: @"DeviceType"]; [context setObject: [[theRequest uri] attachmentName] forKey: @"AttachmentName"]; - cmdName = [[theRequest uri] command]; // We make sure our cache table exists @@ -2142,15 +2569,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { d = [[theRequest content] wbxml2xml]; } - + documentElement = nil; if (!d) { // We check if it's a Ping command with no body. // See http://msdn.microsoft.com/en-us/library/ee200913(v=exchg.80).aspx for details - if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame) - return [NSException exceptionWithHTTPStatus: 500]; + if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"Sync"] != NSOrderedSame) + { + RELEASE(context); + RELEASE(pool); + return [NSException exceptionWithHTTPStatus: 500]; + } } if (d) @@ -2165,28 +2596,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } else { - // Ping command with empty body + // Ping or Sync command with empty body cmdName = [NSString stringWithFormat: @"process%@:inResponse:", cmdName]; } - + aSelector = NSSelectorFromString(cmdName); + // The -processItemOperations: method will generate a multipart response when Content-Type is application/vnd.ms-sync.multipart + if ([[theRequest headerForKey: @"MS-ASAcceptMultiPart"] isEqualToString:@"T"]) + [theResponse setHeader: @"application/vnd.ms-sync.multipart" forKey: @"Content-Type"]; + else + [theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"]; + [self performSelector: aSelector withObject: documentElement withObject: theResponse]; - [theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"]; [theResponse setHeader: @"14.1" forKey: @"MS-Server-ActiveSync"]; [theResponse setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"]; - [theResponse setHeader: @"2.0,2.1,2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"]; + [theResponse setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"]; - RELEASE(context); + RELEASE(context); + RELEASE(pool); return nil; } - (NSURL *) folderTableURL { - NSString *urlString, *ocFSTableName; + NSMutableString *ocFSTableName; NSMutableArray *parts; + NSString *urlString; SOGoUser *user; if (!folderTableURL) @@ -2205,10 +2643,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* If "OCSFolderInfoURL" is properly configured, we must have 5 parts in this url. We strip the '-' character in case we have this in the domain part - like foo@bar-zot.com */ - ocFSTableName = [NSString stringWithFormat: @"sogo_cache_folder_%@", - [[[user loginInDomain] asCSSIdentifier] - stringByReplacingOccurrencesOfString: @"-" - withString: @"_"]]; + ocFSTableName = [NSMutableString stringWithFormat: @"sogo_cache_folder_%@", + [[user loginInDomain] asCSSIdentifier]]; + [ocFSTableName replaceOccurrencesOfString: @"-" + withString: @"_" + options: 0 + range: NSMakeRange(0, [ocFSTableName length])]; [parts replaceObjectAtIndex: 4 withObject: ocFSTableName]; folderTableURL = [NSURL URLWithString: [parts componentsJoinedByString: @"/"]]; diff --git a/ActiveSync/SOGoMailObject+ActiveSync.m b/ActiveSync/SOGoMailObject+ActiveSync.m index e5f349092..6cc06e3d0 100644 --- a/ActiveSync/SOGoMailObject+ActiveSync.m +++ b/ActiveSync/SOGoMailObject+ActiveSync.m @@ -30,7 +30,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "SOGoMailObject+ActiveSync.h" #import -#import #import #import #import @@ -67,8 +66,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include - #include +#include typedef struct { uint32_t dwLowDateTime; @@ -283,7 +282,7 @@ struct GlobalObjectId { performed: b]; } } - else if ([thePart isKindOfClass: [NGMimeBodyPart class]]) + else if ([thePart isKindOfClass: [NGMimeBodyPart class]] || [thePart isKindOfClass: [NGMimeMessage class]]) { NGMimeFileData *fdata; id body; @@ -323,6 +322,11 @@ struct GlobalObjectId { if (s) { + // We sanitize the content immediately, in case we have non-UNICODE safe + // characters that would be re-encoded later in HTML entities and thus, + // ignore afterwards. + s = [s safeString]; + body = [s dataUsingEncoding: NSUTF8StringEncoding]; } @@ -362,8 +366,7 @@ struct GlobalObjectId { if (message) { - [self _sanitizedMIMEPart: [message body] - performed: &b]; + [self _sanitizedMIMEPart: message performed: &b]; if (b) { @@ -506,7 +509,6 @@ struct GlobalObjectId { // - (NSString *) activeSyncRepresentationInContext: (WOContext *) _context { - NSAutoreleasePool *pool; NSData *d, *globalObjId; NSArray *attachmentKeys; NSMutableString *s; @@ -699,10 +701,6 @@ struct GlobalObjectId { // Body - namespace 17 preferredBodyType = [[context objectForKey: @"BodyPreferenceType"] intValue]; - // Make use of a local pool here as _preferredBodyDataUsingType:nativeType: will consume - // a significant amout of RAM and file descriptors - pool = [[NSAutoreleasePool alloc] init]; - nativeBodyType = 1; d = [self _preferredBodyDataUsingType: preferredBodyType nativeType: &nativeBodyType]; @@ -742,9 +740,7 @@ struct GlobalObjectId { } [s appendString: @""]; } - - DESTROY(pool); - + // Attachments -namespace 16 attachmentKeys = [self fetchFileAttachmentKeys]; if ([attachmentKeys count]) diff --git a/ActiveSync/SOGoSyncCacheObject.m b/ActiveSync/SOGoSyncCacheObject.m index ab973348d..63c545b34 100644 --- a/ActiveSync/SOGoSyncCacheObject.m +++ b/ActiveSync/SOGoSyncCacheObject.m @@ -55,7 +55,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [o setUID: theUID]; [o setSequence: theSequence]; - return o; + return [o autorelease]; } - (void) dealloc diff --git a/ActiveSync/SoObjectWebDAVDispatcher+ActiveSync.m b/ActiveSync/SoObjectWebDAVDispatcher+ActiveSync.m index f45f2081a..7196ff002 100644 --- a/ActiveSync/SoObjectWebDAVDispatcher+ActiveSync.m +++ b/ActiveSync/SoObjectWebDAVDispatcher+ActiveSync.m @@ -61,7 +61,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [response setHeader: @"private" forKey: @"Cache-Control"]; [response setHeader: @"OPTIONS, POST" forKey: @"Allow"]; [response setHeader: @"14.1" forKey: @"MS-Server-ActiveSync"]; - [response setHeader: @"2.0,2.1,2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"]; + [response setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"]; [response setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"]; [response setHeader: @"OPTIONS, POST" forKey: @"Public"]; } diff --git a/ActiveSync/common.make b/ActiveSync/common.make index 505f53f88..bf77fa3be 100644 --- a/ActiveSync/common.make +++ b/ActiveSync/common.make @@ -16,10 +16,11 @@ ADDITIONAL_INCLUDE_DIRS += \ -I../../SOPE ADDITIONAL_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/ \ + -L../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo \ -L../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR)/ \ -L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \ - -L/usr/local/lib + -L/usr/local/lib \ + -Wl,-rpath,$(SOGO_SYSLIBDIR)/sogo BUNDLE_LIBS += \ -lSOGo \ diff --git a/ActiveSync/iCalEvent+ActiveSync.m b/ActiveSync/iCalEvent+ActiveSync.m index bbffb0292..d1a4b6f8a 100644 --- a/ActiveSync/iCalEvent+ActiveSync.m +++ b/ActiveSync/iCalEvent+ActiveSync.m @@ -76,13 +76,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (NSString *) activeSyncRepresentationInContext: (WOContext *) context { NSMutableString *s; - NSArray *attendees; + NSArray *attendees, *categories; iCalPerson *organizer, *attendee; iCalTimeZone *tz; id o; - int v; + int v, i, meetingStatus; NSTimeZone *userTimeZone; userTimeZone = [[[context activeUser] userDefaults] timeZone]; @@ -127,13 +127,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. tz = [(iCalDateTime *)[self firstChildWithTag: @"dtstart"] timeZone]; if (!tz) - tz = [iCalTimeZone timeZoneForName: @"Europe/London"]; + tz = [iCalTimeZone timeZoneForName: [userTimeZone name]]; [s appendFormat: @"%@", [tz activeSyncRepresentationInContext: context]]; // Organizer and other invitations related properties if ((organizer = [self organizer])) { + meetingStatus = 1; // meeting and the user is the meeting organizer. o = [organizer rfc822Email]; if ([o length]) { @@ -159,7 +160,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [s appendString: @""]; attendee = [attendees objectAtIndex: i]; - [s appendFormat: @"%@", [attendee rfc822Email]]; + [s appendFormat: @"%@", [[attendee rfc822Email] activeSyncRepresentationInContext: context]]; [s appendFormat: @"%@", [[attendee cn] activeSyncRepresentationInContext: context]]; attendee_status = [self _attendeeStatus: attendee]; @@ -177,6 +178,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } [s appendString: @""]; } + else + { + meetingStatus = 0; // appointment + } // This depends on the 'NEEDS-ACTION' parameter. // This will trigger the SendMail command @@ -186,18 +191,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int attendee_status; + meetingStatus = 3; // event is a meeting, and the user is not the meeting organizer + attendee = [self userAsAttendee: [context activeUser]]; attendee_status = [self _attendeeStatus: attendee]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", attendee_status]; - [s appendFormat: @"%d", 3]; [s appendFormat: @"%d", 1]; // BusyStatus -- http://msdn.microsoft.com/en-us/library/ee202290(v=exchg.80).aspx [s appendFormat: @"%d", 2]; } + [s appendFormat: @"%d", meetingStatus]; + // Subject -- http://msdn.microsoft.com/en-us/library/ee157192(v=exchg.80).aspx if ([[self summary] length]) [s appendFormat: @"%@", [[self summary] activeSyncRepresentationInContext: context]]; @@ -223,12 +231,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Sensitivity if ([[self accessClass] isEqualToString: @"PRIVATE"]) v = 2; - if ([[self accessClass] isEqualToString: @"CONFIDENTIAL"]) + else if ([[self accessClass] isEqualToString: @"CONFIDENTIAL"]) v = 3; else v = 0; [s appendFormat: @"%d", v]; + + categories = [self categories]; + + if ([categories count]) + { + [s appendFormat: @""]; + for (i = 0; i < [categories count]; i++) + { + [s appendFormat: @"%@", [[categories objectAtIndex: i] activeSyncRepresentationInContext: context]]; + } + [s appendFormat: @""]; + } + // Reminder -- http://msdn.microsoft.com/en-us/library/ee219691(v=exchg.80).aspx // TODO: improve this to handle more alarm types @@ -250,11 +271,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. o = [self comment]; if ([o length]) { + // It is very important here to NOT set 0 in the response, + // otherwise it'll prevent WP8 phones from sync'ing. See #3028 for details. o = [o activeSyncRepresentationInContext: context]; [s appendString: @""]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", [o length]]; - [s appendFormat: @"%d", 0]; [s appendFormat: @"%@", o]; [s appendString: @""]; } @@ -310,7 +332,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. iCalTimeZone *tz; id o; - NSInteger tzOffset; BOOL isAllDay; if ((o = [theValues objectForKey: @"UID"])) @@ -334,18 +355,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [o intValue]; } - // - // - // - if ((o = [theValues objectForKey: @"MeetingStatus"])) - { - [o intValue]; - } - // // 0- normal, 1- personal, 2- private and 3-confidential // - if ((o = [theValues objectForKey: @"Sensitivy"])) + if ((o = [theValues objectForKey: @"Sensitivity"])) { switch ([o intValue]) { @@ -362,9 +375,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } } - if ((o = [theValues objectForKey: @"TimeZone"])) + // Categories + if ((o = [theValues objectForKey: @"Categories"]) && [o length]) + [self setCategories: o]; + + // We ignore TimeZone sent by mobile devices for now. + // Some Windows devices don't send during event updates. + //if ((o = [theValues objectForKey: @"TimeZone"])) + // { + // } + //else { - // Ugh, we ignore it for now. + // We haven't received a timezone, let's use the user's timezone + // specified in SOGo for now. userTimeZone = [[[context activeUser] userDefaults] timeZone]; tz = [iCalTimeZone timeZoneForName: [userTimeZone name]]; [(iCalCalendar *) parent addTimeZone: tz]; @@ -383,21 +406,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. start = (iCalDateTime *) [self uniqueChildWithTag: @"dtstart"]; [start setTimeZone: tz]; - if (isAllDay) - { - tzOffset = [userTimeZone secondsFromGMTForDate: o]; - o = [o dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: tzOffset]; + if (isAllDay) + { [start setDate: o]; [start setTimeZone: nil]; } else { - tzOffset = [userTimeZone secondsFromGMTForDate: o]; - o = [o dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: tzOffset]; [start setDateTime: o]; } } @@ -410,19 +425,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (isAllDay) { - tzOffset = [userTimeZone secondsFromGMTForDate: o]; - o = [o dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: tzOffset]; [end setDate: o]; [end setTimeZone: nil]; } else { - tzOffset = [userTimeZone secondsFromGMTForDate: o]; - o = [o dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: tzOffset]; [end setDateTime: o]; } } @@ -481,11 +488,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [self setOrganizer: person]; } + // + // iOS is plain stupid here. It seends event invitations with no Organizer. + // We check this corner-case and if MeetingStatus == 1 (see http://msdn.microsoft.com/en-us/library/ee219342(v=exchg.80).aspx or details) + // and there's no organizer, we fake one. + // + if ((o = [theValues objectForKey: @"MeetingStatus"])) + { + if ([o intValue] == 1 && ![theValues objectForKey: @"Organizer_Email"]) + { + iCalPerson *person; + + person = [iCalPerson elementWithTag: @"organizer"]; + [person setEmail: [[[context activeUser] primaryIdentity] objectForKey: @"email"]]; + [person setCn: [[context activeUser] cn]]; + [person setPartStat: @"ACCEPTED"]; + [self setOrganizer: person]; + } + } + + // Attendees - we don't touch the values if we're an attendee. This is gonna // be done automatically by the ActiveSync client when invoking MeetingResponse. if (![self userIsAttendee: [context activeUser]]) { - if ((o = [theValues objectForKey: @"Attendees"])) + // Windows phones sens sometimes an empty Attendees tag. + // We check it's an array before processing it. + if ((o = [theValues objectForKey: @"Attendees"])&& [o isKindOfClass: [NSArray class]]) { NSMutableArray *attendees; NSDictionary *attendee; diff --git a/ActiveSync/iCalTimeZone+ActiveSync.m b/ActiveSync/iCalTimeZone+ActiveSync.m index 0670acc11..c4c0071fd 100644 --- a/ActiveSync/iCalTimeZone+ActiveSync.m +++ b/ActiveSync/iCalTimeZone+ActiveSync.m @@ -76,15 +76,17 @@ struct SYSTEMTIME { byMonth = [rrule byMonth]; if ([byMonth count] > 0) { + tzData->wYear = 0; tzData->wMonth = [[byMonth objectAtIndex: 0] intValue]; mask = [rrule byDayMask]; tzData->wDayOfWeek = [mask firstDay]; - tzData->wDay = [mask firstOccurrence]; + tzData->wDay = ([mask firstOccurrence] == -1) ? 5 : [mask firstOccurrence]; dateValue = [self startDate]; tzData->wHour = [dateValue hourOfDay]; tzData->wMinute = [dateValue minuteOfHour]; tzData->wSecond = [dateValue secondOfMinute]; + tzData->wMilliseconds = 0; } } diff --git a/ActiveSync/iCalToDo+ActiveSync.m b/ActiveSync/iCalToDo+ActiveSync.m index d09fda688..5f237a31b 100644 --- a/ActiveSync/iCalToDo+ActiveSync.m +++ b/ActiveSync/iCalToDo+ActiveSync.m @@ -54,9 +54,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (NSString *) activeSyncRepresentationInContext: (WOContext *) context { NSMutableString *s; + NSArray *categories; id o; - int v; + int v, i; s = [NSMutableString string]; @@ -96,9 +97,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Reminder - FIXME [s appendFormat: @"%d", 0]; - // Sensitivity - FIXME - [s appendFormat: @"%d", 0]; - + if ([[self accessClass] isEqualToString: @"PRIVATE"]) + v = 2; + else if ([[self accessClass] isEqualToString: @"CONFIDENTIAL"]) + v = 3; + else + v = 0; + + categories = [self categories]; + + if ([categories count]) + { + [s appendFormat: @""]; + for (i = 0; i < [categories count]; i++) + { + [s appendFormat: @"%@", [[categories objectAtIndex: i] activeSyncRepresentationInContext: context]]; + } + [s appendFormat: @""]; + } + // Subject o = [self summary]; if ([o length]) @@ -106,11 +123,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if ((o = [self comment])) { + // It is very important here to NOT set 0 in the response, + // otherwise it'll prevent WP8 phones from sync'ing. See #3028 for details. o = [o activeSyncRepresentationInContext: context]; [s appendString: @""]; [s appendFormat: @"%d", 1]; [s appendFormat: @"%d", [o length]]; - [s appendFormat: @"%d", 0]; [s appendFormat: @"%@", o]; [s appendString: @""]; } @@ -125,8 +143,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. iCalTimeZone *tz; id o; - NSInteger tzOffset; - userTimeZone = [[[context activeUser] userDefaults] timeZone]; tz = [iCalTimeZone timeZoneForName: [userTimeZone name]]; [(iCalCalendar *) parent addTimeZone: tz]; @@ -147,10 +163,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. o = [o calendarDate]; completed = (iCalDateTime *) [self uniqueChildWithTag: @"completed"]; - //tzOffset = [[o timeZone] secondsFromGMTForDate: o]; - //o = [o dateByAddingYears: 0 months: 0 days: 0 - // hours: 0 minutes: 0 - // seconds: -tzOffset]; [completed setDate: o]; [self setStatus: @"COMPLETED"]; } @@ -159,15 +171,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { iCalDateTime *due; - o = [o calendarDate]; due = (iCalDateTime *) [self uniqueChildWithTag: @"due"]; [due setTimeZone: tz]; - - tzOffset = [userTimeZone secondsFromGMTForDate: o]; - o = [o dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: tzOffset]; [due setDateTime: o]; } @@ -182,6 +188,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [self setPriority: @"9"]; } + // + // 0- normal, 1- personal, 2- private and 3-confidential + // + if ((o = [theValues objectForKey: @"Sensitivity"])) + { + switch ([o intValue]) + { + case 2: + [self setAccessClass: @"PRIVATE"]; + break; + case 3: + [self setAccessClass: @"CONFIDENTIAL"]; + break; + case 0: + case 1: + default: + [self setAccessClass: @"PUBLIC"]; + } + } + + // Categories + if ((o = [theValues objectForKey: @"Categories"]) && [o length]) + [self setCategories: o]; if ((o = [theValues objectForKey: @"ReminderTime"])) { diff --git a/Apache/SOGo.conf b/Apache/SOGo.conf index bfe7560ba..3dd0df476 100644 --- a/Apache/SOGo.conf +++ b/Apache/SOGo.conf @@ -26,12 +26,23 @@ Alias /SOGo/WebServerResources/ \ ## need to set the "SOGoTrustProxyAuthentication" SOGo user default to YES and ## adjust the "x-webobjects-remote-user" proxy header in the "Proxy" section ## below. +# +## For full proxy-side authentication: # # AuthType XXX # Require valid-user # SetEnv proxy-nokeepalive 1 # Allow from all # +# +## For proxy-side authentication only for CardDAV and GroupDAV from external +## clients: +# +# AuthType XXX +# Require valid-user +# SetEnv proxy-nokeepalive 1 +# Allow from all +# ProxyRequests Off SetEnv proxy-nokeepalive 1 @@ -64,7 +75,8 @@ ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0 ## When using proxy-side autentication, you need to uncomment and ## adjust the following line: -# RequestHeader set "x-webobjects-remote-user" "%{REMOTE_USER}e" + RequestHeader unset "x-webobjects-remote-user" +# RequestHeader set "x-webobjects-remote-user" "%{REMOTE_USER}e" env=REMOTE_USER RequestHeader set "x-webobjects-server-protocol" "HTTP/1.0" diff --git a/ChangeLog b/ChangeLog index baaa62e66..ab90551ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,2491 @@ +commit d1d398091961f5d497b67313e098a8a5624089f4 +Author: Francis Lachapelle +Date: Fri Jan 30 11:03:38 2015 -0500 + + Update translations + +M NEWS +M UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings +M UI/PreferencesUI/Hungarian.lproj/Localizable.strings + +commit cf35eec1f5c56d8c7332bed34e2195a8ad9c9e9f +Author: Ludovic Marcotte +Date: Fri Jan 30 10:28:45 2015 -0500 + + Improved the NEWS file for the release + +M NEWS + +commit 58a0b0c173616db9a3a1592b437dba7e40475321 +Author: Ludovic Marcotte +Date: Fri Jan 30 10:23:04 2015 -0500 + + Updated for the release + +M NEWS + +commit 723a9d4e080644a7a8cef60de9b7450621f0964e +Author: Ludovic Marcotte +Date: Thu Jan 29 16:21:06 2015 -0500 + + Reverted bug fix from #3054 and added comment + +M SoObjects/SOGo/SOGoParentFolder.m + +commit 4cc158043eb6183ecefed7abd93b579afbdfd7f6 +Author: Francis Lachapelle +Date: Wed Jan 28 16:38:27 2015 -0500 + + Improve CSS server-side cleaner + + Fixes #3040 + +M UI/MailPartViewers/UIxMailPartHTMLViewer.m + +commit 7fd1564a86d50cc96995bd3dec44939741312f4a +Author: Ludovic Marcotte +Date: Wed Jan 28 15:16:21 2015 -0500 + + fix for #3076 + +M ActiveSync/SOGoActiveSyncDispatcher.m +M ActiveSync/SoObjectWebDAVDispatcher+ActiveSync.m +M Documentation/SOGoInstallationGuide.asciidoc +M NEWS + +commit 981c718d228f70a23e73d8db913234be7161166c +Author: Ludovic Marcotte +Date: Wed Jan 28 15:03:49 2015 -0500 + + improved handling of EAS Push when no heartbeat is provided + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS + +commit 086361b79a8be7722d8ae476140858067bb06c2a +Author: Ludovic Marcotte +Date: Fri Jan 23 16:16:36 2015 -0500 + + Avoid GNUstep warnings + +M SOPE/GDLContentStore/GCSFolderType.m +M UI/MailerUI/UIxMailEditor.m + +commit ab12c84887a663c0ec442cfa22b2c9fd1f737f24 +Author: Ludovic Marcotte +Date: Fri Jan 23 15:32:22 2015 -0500 + + More NSLog usage cleanups + +M SoObjects/Appointments/iCalCalendar+SOGo.m +M SoObjects/Mailer/NSData+Mail.h +M SoObjects/Mailer/NSData+Mail.m +M SoObjects/SOGo/BSONCodec.m +M SoObjects/SOGo/SOGoMailer.m +M SoObjects/SOGo/SOGoSieveManager.m +M SoObjects/SOGo/SOGoWebDAVAclManager.m + +commit e2bee230217d16287883fb595d7bfc7ddec0ff77 +Author: Ludovic Marcotte +Date: Thu Jan 22 16:25:16 2015 -0500 + + Avoid unnecessary calls to NSLog + +M UI/Contacts/UIxListView.m +M UI/MailPartViewers/UIxMailPartHTMLViewer.m +M UI/MailerUI/UIxMailView.m +M UI/Scheduler/UIxCalView.m +M UI/Scheduler/UIxComponentEditor.m + +commit 1a10599369da87e64b77cf110624ca6745605585 +Author: Ludovic Marcotte +Date: Thu Jan 22 15:39:57 2015 -0500 + + Removed unnecessary NSLog calls + +M SOPE/NGCards/CardGroup.m +M SOPE/NGCards/IcalResponse.m +M SOPE/NGCards/NSCalendarDate+ICal.m +M SOPE/NGCards/NSString+NGCards.m +M SOPE/NGCards/iCalObject.m + +commit d907d5d268b470c7f461cb0b7951b894e4b77772 +Author: Ludovic Marcotte +Date: Thu Jan 22 13:31:31 2015 -0500 + + Avoid using NSLog() where we can + +M ActiveSync/NSData+ActiveSync.m +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m +M Main/SOGo.m +M Main/sogod.m + +commit d98ff69fbee723ae268b0cb0836c8dca75394743 +Author: Ludovic Marcotte +Date: Tue Jan 20 08:35:10 2015 -0500 + + Version bumps for the release + +M ChangeLog +M Documentation/docinfo.xml +M Documentation/includes/global-attributes.asciidoc +M NEWS +M Version + +commit daa7ab87d7de8553c4df8790a10f18dead51e61f +Author: Ludovic Marcotte +Date: Mon Jan 19 13:54:04 2015 -0500 + + Fix cosmetic change when fetching fb info + +M Documentation/SOGoInstallationGuide.asciidoc +M UI/MainUI/SOGoUserHomePage.m + +commit 3e59b1ad6eb4dcca87b75fc478931bb9a404900e +Author: Ludovic Marcotte +Date: Fri Jan 16 12:55:38 2015 -0500 + + Improved documentation regarding password policies over LDAP + +M Documentation/SOGoInstallationGuide.asciidoc + +commit e45451a9f9a38f869268f4db47e4e24045b63530 +Author: Ludovic Marcotte +Date: Fri Jan 16 09:18:37 2015 -0500 + + Improved comments over previous commit + +M SOPE/NGCards/iCalTimeZonePeriod.m + +commit e9e3dd5646cdf004896f350e35fddd661463f029 +Author: Ludovic Marcotte +Date: Thu Jan 15 15:29:02 2015 -0500 + + fixed timezone calculation on recurring event + +M NEWS +M SOPE/NGCards/iCalTimeZonePeriod.m +M SoObjects/Appointments/SOGoAppointmentFolder.m + +commit 16c863d89dc7555d3c1a490c3467c08c00bd421f +Author: Ludovic Marcotte +Date: Thu Jan 15 11:55:04 2015 -0500 + + Fixed potential issue when handling multiple Add/Change/Delete/Fetch EAS commands (#3057) + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M NEWS + +commit d87056ebfadff870518d032a0fbbd52d5c6d0a88 +Author: Ludovic Marcotte +Date: Mon Jan 12 14:38:55 2015 -0500 + + handle multipart for EAS/ItemOperations + +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS + +commit 135b463e8fa770f47aadb58ede53898ce6a8bfdc +Author: Ludovic Marcotte +Date: Mon Jan 12 13:39:06 2015 -0500 + + Updated the EAS doc + +M ActiveSync/README +M Documentation/SOGoInstallationGuide.asciidoc + +commit f4c4f5af6271956de6a9a339d8834b4f2f66ea45 +Author: Ludovic Marcotte +Date: Mon Jan 12 09:09:06 2015 -0500 + + fixed From's full name over EAS + +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS + +commit 70e45f78430e07f75e1fe094f8087902f572fab6 +Author: Ludovic Marcotte +Date: Mon Jan 12 08:40:06 2015 -0500 + + fixed birthday offset in EAS + +M ActiveSync/NGVCard+ActiveSync.m +M NEWS + +commit 28e449b05077b2f0686fae645a84447af1b6d4e8 +Author: Ludovic Marcotte +Date: Sat Jan 10 07:55:55 2015 -0500 + + Updated NEWS file for bugs fixed + +M NEWS + +commit 6b52e9c945af28188b221f4cbf26e0ee28f58195 +Author: Ludovic Marcotte +Date: Fri Jan 9 09:04:15 2015 -0500 + + Fix for bug #2960 + +M NEWS +M SoObjects/SOGo/WOContext+SOGo.h +M SoObjects/SOGo/WOContext+SOGo.m +M SoObjects/SOGo/WORequest+SOGo.h +M SoObjects/SOGo/WORequest+SOGo.m + +commit 1cfbea69c14468424f5eb713bcb5918a70b3d676 +Author: Ludovic Marcotte +Date: Thu Jan 8 15:56:16 2015 -0500 + + Make sure we always release local pool + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m + +commit cb9118d869d1d2535c50d46df5457038160de59e +Author: Ludovic Marcotte +Date: Wed Jan 7 09:29:31 2015 -0500 + + Moved the pool destruction at the correct location + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m + +commit dd6dd7251ca15dc5e758e733e2529003e08e7c7c +Author: Francis Lachapelle +Date: Tue Jan 6 13:59:20 2015 -0500 + + Fix selection of calendar in event/task editors + + Fixes #3049 + Fixes #3050 + +M UI/Scheduler/UIxComponentEditor.m +M UI/Templates/SchedulerUI/UIxAppointmentEditor.wox +M UI/Templates/SchedulerUI/UIxTaskEditor.wox + +commit 24c6c8c91d421594bd51f07904d4cd3911cd187c +Author: Ludovic Marcotte +Date: Tue Jan 6 10:59:56 2015 -0500 + + Fix for bug #3054 + +M NEWS +M SoObjects/Appointments/SOGoAppointmentFolders.m +M SoObjects/SOGo/SOGoFolder.h +M SoObjects/SOGo/SOGoFolder.m +M SoObjects/SOGo/SOGoGCSFolder.h +M SoObjects/SOGo/SOGoObject.h +M SoObjects/SOGo/SOGoObject.m +M SoObjects/SOGo/SOGoParentFolder.h +M SoObjects/SOGo/SOGoParentFolder.m + +commit b1ac7a0cca0ace6aecd3ee650e3029ca16709831 +Author: Ludovic Marcotte +Date: Mon Jan 5 13:49:28 2015 -0500 + + MultipleBookingsFieldName can be set to -1 + +M Documentation/SOGoInstallationGuide.asciidoc +M NEWS +M SoObjects/Appointments/SOGoAppointmentObject.m +M SoObjects/SOGo/SOGoUser.m +M SoObjects/SOGo/SOGoUserManager.h +M SoObjects/SOGo/SOGoUserManager.m +M UI/MainUI/SOGoUserHomePage.m + +commit 59e6d6df4aa131ca1ea658a212ec1c30e516b5f1 +Author: Francis Lachapelle +Date: Mon Jan 5 10:12:57 2015 -0500 + + Fix selection of calendar in event/task editors + + Fixes #3049 + Fixes #3050 + +M NEWS +M UI/Templates/SchedulerUI/UIxAppointmentEditor.wox +M UI/Templates/SchedulerUI/UIxTaskEditor.wox + +commit 71ad5de910de96a293f75c7c0caba7a36b96c020 +Author: Ludovic Marcotte +Date: Tue Dec 30 08:00:41 2014 -0500 + + Bumped everything for the release + +M ChangeLog +M Documentation/docinfo.xml +M Documentation/includes/global-attributes.asciidoc +M NEWS +M Version + +commit ead665de85e2202dbde926c316cbba927d38dfa7 +Author: Ludovic Marcotte +Date: Mon Dec 29 16:19:10 2014 -0500 + + fix tz issue when the user one was different from the system one with EAS + +M ActiveSync/NSString+ActiveSync.m +M ActiveSync/iCalEvent+ActiveSync.m +M ActiveSync/iCalToDo+ActiveSync.m +M NEWS + +commit a0c1ce8f3b7c22002661d40c24e95a1233b6a6e8 +Author: Ludovic Marcotte +Date: Mon Dec 29 12:43:20 2014 -0500 + + Improved handling of non-existant vs. subscribed folders over EAS + +M ActiveSync/SOGoActiveSyncDispatcher.m +M SoObjects/Mailer/SOGoMailAccount.m +M SoObjects/Mailer/SOGoMailFolder.m + +commit 204a62aa6ac8feb5a13d5a2ee162bb26cc495a50 +Author: Ludovic Marcotte +Date: Tue Dec 23 10:25:53 2014 -0500 + + Improved comments in the code + +M SoObjects/Appointments/SOGoAppointmentFolder.m + +commit 31cffdffd34429d1f4873d07d67e822bff82b7cf +Author: Ludovic Marcotte +Date: Tue Dec 23 10:24:16 2014 -0500 + + Fix freebusy info not always returned + +M NEWS +M SoObjects/Appointments/SOGoAppointmentFolder.m +M SoObjects/SOGo/SOGoFolder.h +M SoObjects/SOGo/SOGoFolder.m + +commit 255bcbe92fa6b4610edf5f4d05c97b74537ecb6e +Author: Ludovic Marcotte +Date: Mon Dec 22 19:59:33 2014 -0500 + + Fixed memory leaks in SOGoSyncCacheObject and correctly kill the cache upon each EAS iteration + +M ActiveSync/SOGoSyncCacheObject.m +M SoObjects/Mailer/SOGoMailBaseObject.m +M SoObjects/SOGo/NSObject+Utilities.m +M UI/MainUI/SOGoMicrosoftActiveSyncActions.m + +commit 72732879fafe8ef928593c0cf3e39d962b096ec9 +Author: Ludovic Marcotte +Date: Mon Dec 22 19:32:17 2014 -0500 + + Added memory statistics - set SOGoDebugLeaks = YES and call [[self class] memoryStatistics] + +M SoObjects/SOGo/NSObject+Utilities.h +M SoObjects/SOGo/NSObject+Utilities.m + +commit 24a934275f5678f7ab86cb706aa817dfb5ef8991 +Author: Ludovic Marcotte +Date: Mon Dec 22 16:12:26 2014 -0500 + + Fix small memory leak incase of errors + +M ActiveSync/SOGoActiveSyncDispatcher.m + +commit 58f634bffe35b3a1f6a02072ba0103fea2155a45 +Author: Ludovic Marcotte +Date: Mon Dec 22 15:26:22 2014 -0500 + + Cosmetic improvements to the code + +M SoObjects/Appointments/SOGoAppointmentObject.m +M SoObjects/SOGo/SOGoMailer.h +M SoObjects/SOGo/SOGoMailer.m + +commit ca4a754f2c12784ff437df34c255d3dccbf5c6f2 +Author: Ludovic Marcotte +Date: Mon Dec 22 12:39:58 2014 -0500 + + Use the right cutoff date + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M NEWS +M SoObjects/SOGo/SOGoGCSFolder.m + +commit 8015688df31a3e3254093b260851d4664d725ea6 +Author: Ludovic Marcotte +Date: Mon Dec 22 11:50:51 2014 -0500 + + Added SOGoMaximumSyncResponseSize to support memory-limited EAS syncs + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M Documentation/SOGoInstallationGuide.asciidoc +M NEWS +M SoObjects/SOGo/SOGoSystemDefaults.h +M SoObjects/SOGo/SOGoSystemDefaults.m + +commit b07913d66d4a47919e09cbcd0c41d92bd97ea0a3 +Author: Ludovic Marcotte +Date: Mon Dec 22 08:36:55 2014 -0500 + + See NEWS file + +M ActiveSync/NGVCard+ActiveSync.m +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS + +commit df8a0d8715d97873e782ccfbfaab8b580c88c66e +Author: Ludovic Marcotte +Date: Fri Dec 19 09:03:37 2014 -0500 + + Update ChangeLog + +M ChangeLog + +commit e6cc56dca1126e09cb8336bdbd4e5dabc7b83cf1 +Author: Ludovic Marcotte +Date: Fri Dec 19 09:03:19 2014 -0500 + + Bumped version to 2.2.12a + +M Version + +commit de3d38262b047a1b72ec9a49042059b90e2abc2c +Author: Ludovic Marcotte +Date: Fri Dec 19 09:01:39 2014 -0500 + + Fix for bug #3034 + +M NEWS +M SoObjects/Mailer/SOGoDraftObject.m + +commit 0e56527e05566e78ac8fe4687d19423de78b0276 +Author: Chris Rosenhain +Date: Fri Dec 19 11:04:05 2014 +1030 + + Change ACL modification text to non-gender specific terms + +M SoObjects/Appointments/SOGoAppointmentObject.m +M SoObjects/Appointments/SOGoCalendarComponent.m +M SoObjects/SOGo/SOGoGCSFolder.m +M SoObjects/SOGo/SOGoUserFolder.h +M UI/MainUI/SOGoRootPage.m +M UI/Templates/SOGoACLDanishModificationAdvisory.wox +M UI/Templates/SOGoACLDanishRemovalAdvisory.wox +M UI/Templates/SOGoACLDutchModificationAdvisory.wox +M UI/Templates/SOGoACLDutchRemovalAdvisory.wox +M UI/Templates/SOGoACLEnglishModificationAdvisory.wox +M UI/Templates/SOGoACLEnglishRemovalAdvisory.wox + +commit db911f323d23f263f5fa9c5fb02d8234127687b3 +Author: Ludovic Marcotte +Date: Thu Dec 18 08:56:23 2014 -0500 + + Updated ChangeLog and version numbers for the release + +M ChangeLog +M Documentation/docinfo.xml +M Documentation/includes/global-attributes.asciidoc +M Version + +commit fcddb37a0dd76f75bb16f9380e8b8a01865d0c4c +Author: Ludovic Marcotte +Date: Thu Dec 18 08:53:31 2014 -0500 + + Fixed typo and bumped for release + +M NEWS + +commit 8e79d4f88ba2b9603f589e1ee300164647217c8d +Author: Francis Lachapelle +Date: Thu Dec 18 08:51:50 2014 -0500 + + Update translations + +M NEWS +M UI/PreferencesUI/Czech.lproj/Localizable.strings +M UI/PreferencesUI/Dutch.lproj/Localizable.strings +M UI/PreferencesUI/Finnish.lproj/Localizable.strings +M UI/PreferencesUI/German.lproj/Localizable.strings +M UI/PreferencesUI/Polish.lproj/Localizable.strings +M UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings + +commit f8ab3d5a427c17d647286bda441d63a98481fdbe +Author: Francis Lachapelle +Date: Thu Dec 18 08:45:27 2014 -0500 + + Update NEWS file + +M NEWS + +commit 8aea5f232e049024047726305a55580807d5e54b +Author: Ludovic Marcotte +Date: Wed Dec 17 16:18:39 2014 -0500 + + Fix for bug #3028 + +M ActiveSync/iCalEvent+ActiveSync.m +M ActiveSync/iCalToDo+ActiveSync.m +M NEWS + +commit 493c366ac42481d99c014eb9746b38bd43d726a2 +Author: Ludovic Marcotte +Date: Wed Dec 17 15:26:02 2014 -0500 + + Fix for bug #3003 + +M ActiveSync/SOGoMailObject+ActiveSync.m +M NEWS + +commit cd70bec9faf8f29159eafb3ae1e63ab9d7a76919 +Author: Ludovic Marcotte +Date: Wed Dec 17 13:57:49 2014 -0500 + + Fix for bug #3008 + +M NEWS +M SoObjects/Appointments/SOGoAppointmentFolder.m + +commit 6027cb50d4d1d351935ef924d957d5876e73d026 +Author: Francis Lachapelle +Date: Tue Dec 16 16:13:59 2014 -0500 + + Fix CSS and templates of component/apptmt editor + +M UI/Templates/SchedulerUI/UIxComponentEditor.wox +M UI/WebServerResources/UIxAppointmentEditor.css +M UI/WebServerResources/UIxComponentEditor.css + +commit eb4d20e50f109e20d4d040b56fecf27513c46c2c +Author: Ludovic Marcotte +Date: Tue Dec 16 13:27:01 2014 -0500 + + Privacy and categories support for tasks + +M ActiveSync/iCalToDo+ActiveSync.m + +commit 70dbcf0418d24f68232383186cb8443ffc269c8b +Author: Ludovic Marcotte +Date: Tue Dec 16 13:24:10 2014 -0500 + + Fix for MeetingStatus applied yesterday + +M ActiveSync/iCalEvent+ActiveSync.m + +commit bfaaf6eb3436cbfca5e8ede5963cd53012eff92a +Author: Ludovic Marcotte +Date: Tue Dec 16 13:17:59 2014 -0500 + + Revert back to using GNUSTEP_SYSTEM_LIBRARIES for teststrings + +M Tests/Integration/GNUmakefile.preamble + +commit 68655deabd942718c318feeb29e407a4c5b499c2 +Author: Ludovic Marcotte +Date: Tue Dec 16 12:36:08 2014 -0500 + + Improved rpath handling (#2996) + +M ActiveSync/common.make +M Main/GNUmakefile +M Tests/Integration/GNUmakefile.preamble +M Tools/GNUmakefile +M configure + +commit 7380b25b7596e58775afb4203dfa35bd5dd29c4f +Author: Ludovic Marcotte +Date: Tue Dec 16 10:55:12 2014 -0500 + + Be a bit more verbose regarding IMAP requirements for EAS + +M Documentation/SOGoInstallationGuide.asciidoc + +commit cbfb927ec91677ed75f3307d8e41b92a59ec45dd +Author: Ludovic Marcotte +Date: Tue Dec 16 10:42:18 2014 -0500 + + Properly escape Attendee's email address in case it contains crap + +M ActiveSync/iCalEvent+ActiveSync.m + +commit 0f2798f017c340cdf1000b771e5e74c2372562fc +Author: Ludovic Marcotte +Date: Tue Dec 16 10:35:32 2014 -0500 + + Lucid fixes for EAS + +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS +M Tools/SOGoToolManageEAS.m + +commit e040805e0d56458d825102fb5920f381026bf09d +Author: Francis Lachapelle +Date: Tue Dec 16 10:07:08 2014 -0500 + + Fix display of dialog in RO appointment editor + +M UI/Templates/SchedulerUI/UIxComponentEditor.wox +M UI/WebServerResources/UIxAppointmentEditor.css + +commit fb6ef3aa8a8d00db1cb00dbdb51b43c51ae3a438 +Author: Ludovic Marcotte +Date: Tue Dec 16 09:20:27 2014 -0500 + + Now possible to set alarms on event invitations + +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS +M SoObjects/Appointments/GNUmakefile +M SoObjects/Appointments/SOGoAppointmentObject.h +M SoObjects/Appointments/SOGoAppointmentObject.m +M SoObjects/Appointments/SOGoComponentOccurence.h +M SoObjects/Appointments/SOGoComponentOccurence.m +A SoObjects/Appointments/iCalAlarm+SOGo.h +A SoObjects/Appointments/iCalAlarm+SOGo.m +M UI/MailPartViewers/UIxMailPartICalActions.m +M UI/Scheduler/GNUmakefile +D UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar +D UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar +D UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar +M UI/Scheduler/UIxAppointmentEditor.m +M UI/Scheduler/UIxComponentEditor.h +M UI/Scheduler/UIxComponentEditor.m +M UI/Scheduler/product.plist +M UI/Templates/SchedulerUI/UIxAppointmentEditor.wox +M UI/Templates/SchedulerUI/UIxComponentEditor.wox +M UI/WebServerResources/SchedulerUI.js +M UI/WebServerResources/UIxAppointmentEditor.js +M UI/WebServerResources/UIxComponentEditor.js + +commit 3eac0f5261bc4bc4aa4c65547d93d29771fe816e +Author: Ludovic Marcotte +Date: Mon Dec 15 19:37:04 2014 -0500 + + Improved NEWS file + +M NEWS + +commit f29a74f82f437ffce96ac15f1ab604218f0a22d6 +Author: Ludovic Marcotte +Date: Mon Dec 15 19:34:51 2014 -0500 + + avoid testing for IMAP ANNOTATION when X-GUID is available + +M NEWS +M SoObjects/Mailer/SOGoMailAccount.m + +commit 20b3d4882d1675be4a7cbed58f99c2f4d9c96f8f +Author: Ludovic Marcotte +Date: Mon Dec 15 19:27:21 2014 -0500 + + MeetingStatus fix affecting iOS devices + +M ActiveSync/iCalEvent+ActiveSync.m +M NEWS + +commit 175b99b9ee69c08a279fa28f585a6bfd040556dd +Author: Ludovic Marcotte +Date: Mon Dec 15 19:25:38 2014 -0500 + + Updated NEWS regarding previous commit + +M NEWS + +commit e79ea7583415b8892e772d92abb55c8ebf688285 +Author: Ludovic Marcotte +Date: Mon Dec 15 19:24:10 2014 -0500 + + Categories and privacy fixes for bug #3022 + +M ActiveSync/iCalEvent+ActiveSync.m + +commit 9cb1f8097c5e195152e729c5052b88e80ceb064a +Author: Ludovic Marcotte +Date: Mon Dec 15 19:23:04 2014 -0500 + + Fix sogo-tool when cleaning up devices + +M Tools/SOGoToolManageEAS.m + +commit 54dabb6861ff32509b084ddcfdd3e9ebabf034fb +Author: Francis Lachapelle +Date: Mon Dec 15 10:52:04 2014 -0500 + + Update CKEditor to version 4.4.6 (+ sourcearea) + + Added an enabled the 'Source Area' plugin to be able to edit the HTML + code directly. + +M NEWS +M UI/WebServerResources/UIxPreferences.js +M UI/WebServerResources/ckeditor/build-config.js +M UI/WebServerResources/ckeditor/ckeditor.js +M UI/WebServerResources/ckeditor/config.js +M UI/WebServerResources/ckeditor/lang/ar.js +M UI/WebServerResources/ckeditor/lang/ca.js +M UI/WebServerResources/ckeditor/lang/cs.js +M UI/WebServerResources/ckeditor/lang/cy.js +M UI/WebServerResources/ckeditor/lang/da.js +M UI/WebServerResources/ckeditor/lang/de.js +M UI/WebServerResources/ckeditor/lang/en.js +M UI/WebServerResources/ckeditor/lang/es.js +M UI/WebServerResources/ckeditor/lang/fi.js +M UI/WebServerResources/ckeditor/lang/fr.js +M UI/WebServerResources/ckeditor/lang/hu.js +M UI/WebServerResources/ckeditor/lang/is.js +M UI/WebServerResources/ckeditor/lang/it.js +M UI/WebServerResources/ckeditor/lang/nb.js +M UI/WebServerResources/ckeditor/lang/nl.js +M UI/WebServerResources/ckeditor/lang/no.js +M UI/WebServerResources/ckeditor/lang/pl.js +M UI/WebServerResources/ckeditor/lang/pt-br.js +M UI/WebServerResources/ckeditor/lang/ru.js +M UI/WebServerResources/ckeditor/lang/sk.js +M UI/WebServerResources/ckeditor/lang/sv.js +M UI/WebServerResources/ckeditor/lang/uk.js +M UI/WebServerResources/ckeditor/plugins/icons.png +M UI/WebServerResources/ckeditor/plugins/icons_hidpi.png +M UI/WebServerResources/ckeditor/plugins/scayt/dialogs/options.js +M UI/WebServerResources/ckeditor/plugins/wsc/dialogs/wsc.js +M UI/WebServerResources/ckeditor/skins/moono/editor.css +M UI/WebServerResources/ckeditor/skins/moono/editor_gecko.css +M UI/WebServerResources/ckeditor/skins/moono/editor_ie.css +M UI/WebServerResources/ckeditor/skins/moono/editor_ie7.css +M UI/WebServerResources/ckeditor/skins/moono/editor_ie8.css +M UI/WebServerResources/ckeditor/skins/moono/editor_iequirks.css +M UI/WebServerResources/ckeditor/skins/moono/icons.png +M UI/WebServerResources/ckeditor/skins/moono/icons_hidpi.png + +commit 6526d587f2726d6087b15e893e619bdcec7412bf +Author: Francis Lachapelle +Date: Thu Dec 11 14:13:56 2014 -0500 + + Localization + +M UI/PreferencesUI/French.lproj/Localizable.strings + +commit 9dd0d6c427a44f089cedef256899fed367899733 +Author: Ludovic Marcotte +Date: Thu Dec 11 13:31:32 2014 -0500 + + Draft autossave feature + +M NEWS +M SoObjects/Mailer/SOGoDraftObject.m +M SoObjects/SOGo/SOGoDefaults.plist +M SoObjects/SOGo/SOGoDomainDefaults.h +M SoObjects/SOGo/SOGoDomainDefaults.m +M SoObjects/SOGo/SOGoUserDefaults.h +M SoObjects/SOGo/SOGoUserDefaults.m +M UI/MailerUI/UIxMailMainFrame.m +M UI/PreferencesUI/English.lproj/Localizable.strings +M UI/PreferencesUI/UIxPreferences.m +M UI/Templates/MailerUI/UIxMailEditor.wox +M UI/Templates/PreferencesUI/UIxPreferences.wox +M UI/WebServerResources/UIxMailEditor.js + +commit 990f782b627ed956755b727ef3b043d5d66cb14c +Author: Ludovic Marcotte +Date: Thu Dec 11 10:01:21 2014 -0500 + + Allow including or not freebusy info from subscribed calendars + +M NEWS +M SoObjects/Appointments/SOGoAppointmentFolder.m +M SoObjects/Appointments/SOGoFreeBusyObject.h +M SoObjects/Appointments/SOGoFreeBusyObject.m +M UI/Scheduler/UIxCalendarProperties.h +M UI/Scheduler/UIxCalendarProperties.m +M UI/Templates/SchedulerUI/UIxCalendarProperties.wox + +commit c8b74686cc0c656b2a0330c28d299a793417035e +Author: Ludovic Marcotte +Date: Wed Dec 10 15:22:32 2014 -0500 + + Update ChangeLog + +M ChangeLog + +commit 16bf299b3b9011d151a598ee06e02e6a96f2249d +Author: Ludovic Marcotte +Date: Wed Dec 10 15:22:01 2014 -0500 + + Version bump for the release + +M Documentation/docinfo.xml +M Documentation/includes/global-attributes.asciidoc +M Version + +commit b8c79664e102abb36ec6e2b978fb7825c0f1841c +Author: Ludovic Marcotte +Date: Wed Dec 10 14:24:51 2014 -0500 + + Update ChangeLog + +M ChangeLog + +commit 3c063e04fb6943a5716e3978e49e9dcef3660b77 +Author: Ludovic Marcotte +Date: Wed Dec 10 14:24:06 2014 -0500 + + v2.2.11a release + bug fix + +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS + +commit ce5e46f5fb7b1392a0025238b8ac9144bd4d2adb +Author: Francis Lachapelle +Date: Wed Dec 10 09:22:03 2014 -0500 + + Remove unused templates from SchedulerUI + +M UI/Scheduler/GNUmakefile +D UI/Scheduler/UIxAptTableView.m +D UI/Templates/SchedulerUI/UIxAppointmentProposal.wox +D UI/Templates/SchedulerUI/UIxAptTableView.wox +D UI/Templates/SchedulerUI/UIxTaskProposal.wox + +commit 1c0e64f169439f0284a1427043c88d5fcc525455 +Author: Ludovic Marcotte +Date: Tue Dec 9 09:09:18 2014 -0500 + + Update ChangeLog + +M ChangeLog + +commit aac6b22ab56f594e2c796d015e949549bf22e517 +Author: Ludovic Marcotte +Date: Tue Dec 9 09:08:54 2014 -0500 + + Preparation for the release + +M Documentation/docinfo.xml +M Documentation/includes/global-attributes.asciidoc +M NEWS +M Version + +commit 39e8f055d702e0d33da6af130403e1fd0287c102 +Author: Jens Erat +Date: Tue Dec 9 13:23:21 2014 +0100 + + Added information on common configuration issues + + A very common issue (watching the mailing list) is not wrapping the + whole configuration in a dictionary. SOGo is not very helpful at + debugging broken configuration files, thus hinting `plparse` already + installed with the GNUstep runtime. + +M Documentation/SOGoInstallationGuide.asciidoc + +commit 64637d842b9b4979324e98d057909d57c86eb9ec +Author: Ludovic Marcotte +Date: Tue Dec 9 07:21:34 2014 -0500 + + Prevent compilation failures with old gcc versions + +M Tools/SOGoToolManageEAS.m + +commit 4e6214d6fcaa278f4039765de2b74fd862ced228 +Author: Jens Erat +Date: Tue Dec 9 13:11:03 2014 +0100 + + Fixed ActiveSync URL in documentation + +M Documentation/SOGoInstallationGuide.asciidoc + +commit 12788c847d5ba3d609848bf52589b4c7f3907595 +Author: Ludovic Marcotte +Date: Mon Dec 8 10:45:34 2014 -0500 + + New sogo-tool feature to manage EAS data + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS +M Tools/GNUmakefile +A Tools/SOGoToolManageEAS.m + +commit 2b95dd2c0a04b28839a721cb3ba40c674f3981b5 +Author: Ludovic Marcotte +Date: Mon Dec 8 10:29:23 2014 -0500 + + Avoid generating GUID for "Other user"/"Shared" folders + +M SoObjects/Mailer/SOGoMailAccount.m + +commit 9e14a37cb81cf1dce955e5e16440fe413e4f656a +Author: Ludovic Marcotte +Date: Mon Dec 8 10:25:37 2014 -0500 + + Improvements over fixes for #2982 + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m + +commit ae0cbfe6a61610acfe3b3325e6cc9ef58332f6b4 +Author: Ludovic Marcotte +Date: Fri Dec 5 13:52:10 2014 -0500 + + Fix for bug #2982 + +M ActiveSync/SOGoActiveSyncDispatcher.m +M NEWS + +commit 3f3673cf5ad2691c04f975dc58a58173e7c6c2ee +Author: Ludovic Marcotte +Date: Thu Dec 4 17:59:17 2014 -0500 + + Added SOGoSAML2LogoutURL + +M Documentation/SOGoInstallationGuide.asciidoc +M SoObjects/SOGo/SOGoSystemDefaults.h +M SoObjects/SOGo/SOGoSystemDefaults.m +M UI/MainUI/SOGoSAML2Actions.m + +commit 9ef4d1f551bcfe597395bc7d9ec7bef2ef3e9a0f +Author: Ludovic Marcotte +Date: Thu Dec 4 12:21:23 2014 -0500 + + Fix for bug #3010 + +M NEWS +M UI/MainUI/SOGoUserHomePage.m + +commit fe9ad9c6e9b43fa276f6e71972ffd9823e4df9de +Author: Ludovic Marcotte +Date: Thu Dec 4 11:27:10 2014 -0500 + + Radically reduced EAS memory usage + +M ActiveSync/NSData+ActiveSync.m +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m +M ActiveSync/SOGoMailObject+ActiveSync.m +M NEWS +M SoObjects/SOGo/SOGoCacheGCSObject.m + +commit 47094b6d91c6375bb48160b355c643a628c139be +Author: extrafu +Date: Tue Dec 2 19:33:54 2014 -0500 + + Update SOGoSAML2Metadata.xml + + Fixed XML template generation. + +M SoObjects/SOGo/SOGoSAML2Metadata.xml + +commit 9ffa32eebdcc5d3b102aa4d86a93590684800cdc +Author: Ludovic Marcotte +Date: Sun Nov 30 17:35:39 2014 -0500 + + Enable SAML support on all Debian-based distro + +M packaging/debian-multiarch/control +M packaging/debian-multiarch/rules +M packaging/debian/control +M packaging/debian/control-squeeze +M packaging/debian/rules + +commit 1b715e0812dba3d9f2c4d3f2daa0cbd4313f8def +Author: Ludovic Marcotte +Date: Thu Nov 27 11:37:08 2014 -0500 + + We now handle correctly the SOGo logout when using SAML (#2376 and #2379) + +M Documentation/SOGoInstallationGuide.asciidoc +M NEWS +M SoObjects/SOGo/SOGoCASSession.h +M SoObjects/SOGo/SOGoCASSession.m +M SoObjects/SOGo/SOGoCache.h +M SoObjects/SOGo/SOGoCache.m +M SoObjects/SOGo/SOGoSAML2Session.h +M SoObjects/SOGo/SOGoSAML2Session.m +M SoObjects/SOGo/SOGoWebAuthenticator.m +M UI/MainUI/SOGoSAML2Actions.m +M UI/MainUI/SOGoUserHomePage.m + +commit c3715c94857efa77e1e38b814e0f0ee09cc9c678 +Author: Ludovic Marcotte +Date: Wed Nov 26 15:27:36 2014 -0500 + + Added additional bugfix for #2982 + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m + +commit be608dc76c7217c62152e869ab17c9b237a4e99a +Author: Ludovic Marcotte +Date: Wed Nov 26 15:09:30 2014 -0500 + + Bug fixes for #2378 and #2377 and documentation improvements + +M Documentation/SOGoInstallationGuide.asciidoc +M NEWS +A SoObjects/SOGo/SOGoSAML2Metadata.xml +M SoObjects/SOGo/SOGoSAML2Session.h +M SoObjects/SOGo/SOGoSAML2Session.m +M UI/MainUI/SOGoSAML2Actions.m +M UI/MainUI/product.plist + +commit 5a5464dc610cddb87b9c07e97699c24a767f5ed7 +Author: Ludovic Marcotte +Date: Wed Nov 26 13:24:04 2014 -0500 + + An other fix for #2930 + +M UI/MainUI/SOGoUserHomePage.m + +commit 89917c941caf9f7c4ca18e498bba06298f7f26f6 +Author: Ludovic Marcotte +Date: Wed Nov 26 13:01:50 2014 -0500 + + New entry for bug #2381 + +M NEWS + +commit 913a75f410d8e4409960e59c110f707ffad47371 +Author: Ludovic Marcotte +Date: Wed Nov 26 13:00:47 2014 -0500 + + Fix for bug # + +M SoObjects/SOGo/SOGoCache.m +M SoObjects/SOGo/SOGoSAML2Session.h +M SoObjects/SOGo/SOGoSAML2Session.m +M SoObjects/SOGo/SOGoSession.h +M SoObjects/SOGo/SOGoSession.m +M SoObjects/SOGo/SOGoSystemDefaults.h +M SoObjects/SOGo/SOGoSystemDefaults.m + +commit 20e728afac25c9930af97eb2d1fb7519d415c853 +Author: Ludovic Marcotte +Date: Tue Nov 25 17:28:12 2014 -0500 + + Remove unnecessary comments + +M SoObjects/SOGo/SOGoCache.m + +commit 5f14bc11011394ff6f1333880320eec7ceb675af +Author: Ludovic Marcotte +Date: Tue Nov 25 17:27:03 2014 -0500 + + Report the correct preference keys + +M SoObjects/SOGo/SOGoSAML2Session.m + +commit b0633ba1f454b9b09d646ff0b512f5d13a0f236e +Author: Robin McCorkell +Date: Tue Jun 18 17:50:28 2013 +0200 + + Add check for remote_user variable for trusted proxy auth + + If trusted proxy authentication is on, yet the proxy did not authenticate the + user, then the default authentication method is used instead of returning 'Unauthorized'. + +M Apache/SOGo.conf +M Main/SOGo.m + +commit bb227443ed632cb03cba58e24259510c9686e1d2 +Author: Ludovic Marcotte +Date: Sat Nov 22 08:14:31 2014 -0500 + + Check lenght of string before trying to use parameters + +M ActiveSync/NSString+ActiveSync.m + +commit efff32e44d1b6df1dfe03f81bbd0e1f449a8fbb2 +Author: Ludovic Marcotte +Date: Fri Nov 21 09:13:11 2014 -0500 + + Update ChangeLog + +M ChangeLog + +commit f7f78eaba6ac5304df937f5b26f5d21979657787 +Author: Francis Lachapelle +Date: Fri Nov 21 09:07:39 2014 -0500 + + Update CKEditor to version 4.4.5 + +M NEWS +M UI/WebServerResources/ckeditor/build-config.js +M UI/WebServerResources/ckeditor/ckeditor.js +M UI/WebServerResources/ckeditor/lang/ar.js +M UI/WebServerResources/ckeditor/lang/ca.js +M UI/WebServerResources/ckeditor/lang/cs.js +M UI/WebServerResources/ckeditor/lang/cy.js +M UI/WebServerResources/ckeditor/lang/da.js +M UI/WebServerResources/ckeditor/lang/de.js +M UI/WebServerResources/ckeditor/lang/es.js +M UI/WebServerResources/ckeditor/lang/fi.js +M UI/WebServerResources/ckeditor/lang/fr.js +M UI/WebServerResources/ckeditor/lang/hu.js +M UI/WebServerResources/ckeditor/lang/is.js +M UI/WebServerResources/ckeditor/lang/it.js +M UI/WebServerResources/ckeditor/lang/nb.js +M UI/WebServerResources/ckeditor/lang/nl.js +M UI/WebServerResources/ckeditor/lang/no.js +M UI/WebServerResources/ckeditor/lang/pl.js +M UI/WebServerResources/ckeditor/lang/pt-br.js +M UI/WebServerResources/ckeditor/lang/ru.js +M UI/WebServerResources/ckeditor/lang/sk.js +M UI/WebServerResources/ckeditor/lang/sv.js +M UI/WebServerResources/ckeditor/lang/uk.js +M UI/WebServerResources/ckeditor/plugins/about/dialogs/about.js +M UI/WebServerResources/ckeditor/plugins/image/dialogs/image.js +M UI/WebServerResources/ckeditor/plugins/link/images/anchor.png +M UI/WebServerResources/ckeditor/plugins/link/images/hidpi/anchor.png +M UI/WebServerResources/ckeditor/skins/moono/editor_ie7.css +M UI/WebServerResources/ckeditor/skins/moono/editor_iequirks.css +M UI/WebServerResources/ckeditor/skins/moono/images/arrow.png +M UI/WebServerResources/ckeditor/skins/moono/images/close.png +M UI/WebServerResources/ckeditor/skins/moono/images/hidpi/close.png +M UI/WebServerResources/ckeditor/skins/moono/images/hidpi/lock-open.png +M UI/WebServerResources/ckeditor/skins/moono/images/hidpi/lock.png +M UI/WebServerResources/ckeditor/skins/moono/images/hidpi/refresh.png +M UI/WebServerResources/ckeditor/skins/moono/images/lock-open.png +M UI/WebServerResources/ckeditor/skins/moono/images/lock.png +M UI/WebServerResources/ckeditor/skins/moono/images/refresh.png + +commit 78ea1473834b84f4cb06656a50b58fc8cf50c2a7 +Author: Francis Lachapelle +Date: Fri Nov 21 08:52:52 2014 -0500 + + Update translations + +M NEWS +M SoObjects/Appointments/BrazilianPortuguese.lproj/Localizable.strings +M SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings +M SoObjects/Contacts/BrazilianPortuguese.lproj/Localizable.strings +M SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings +M UI/AdministrationUI/SpanishArgentina.lproj/Localizable.strings +M UI/Common/BrazilianPortuguese.lproj/Localizable.strings +M UI/Common/SpanishArgentina.lproj/Localizable.strings +M UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings +M UI/MailPartViewers/BrazilianPortuguese.lproj/Localizable.strings +M UI/MailPartViewers/SpanishArgentina.lproj/Localizable.strings +M UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings +M UI/MailerUI/SpanishArgentina.lproj/Localizable.strings +M UI/MainUI/SpanishArgentina.lproj/Localizable.strings +M UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings +M UI/PreferencesUI/Czech.lproj/Localizable.strings +M UI/PreferencesUI/Dutch.lproj/Localizable.strings +M UI/PreferencesUI/Finnish.lproj/Localizable.strings +M UI/PreferencesUI/French.lproj/Localizable.strings +M UI/PreferencesUI/German.lproj/Localizable.strings +M UI/PreferencesUI/Hungarian.lproj/Localizable.strings +M UI/PreferencesUI/Polish.lproj/Localizable.strings +M UI/PreferencesUI/Russian.lproj/Localizable.strings +M UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings +M UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings +M UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings +M UI/Scheduler/SpanishArgentina.lproj/Localizable.strings + +commit f7935c6084e0ba5e933c639f115120177e68534c +Author: Ludovic Marcotte +Date: Fri Nov 21 08:29:25 2014 -0500 + + Bumped version numbers for the releasex + +M Documentation/docinfo.xml +M Documentation/includes/global-attributes.asciidoc +M NEWS + +commit 327147f7162c1df4f37ff96f6ce815e48cab9bf7 +Author: Ludovic Marcotte +Date: Wed Nov 19 12:07:50 2014 -0500 + + Fixed typo + +M Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc + +commit b4718f363bd439b5521ef1f13946a20ffe5cd408 +Author: Ludovic Marcotte +Date: Wed Nov 19 12:06:44 2014 -0500 + + More documentation fixes for v2.2.10 + +M Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc + +commit 95e3c7ca88403003305c2bf32166fdeac45f0005 +Author: Ludovic Marcotte +Date: Tue Nov 18 18:36:59 2014 -0500 + + More doc fixes for v2.2.10 + +M Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc + +commit 6bbaf58d437a1233519800758711624dc8f9a998 +Author: Ludovic Marcotte +Date: Tue Nov 18 16:56:45 2014 -0500 + + Initial pass of the doc for v2.2.10 on Debian/Ubuntu + +M Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc + +commit ac55509aea982d07c02d429f88131d8da468181b +Author: Ludovic Marcotte +Date: Tue Nov 18 12:45:15 2014 -0500 + + Updated NEWS file regarding the SOPE commit for bug #2957 + +M NEWS + +commit 19221beb1fc0aab45c0b7bcc5fb9ccd9e7561f73 +Author: Jens Erat +Date: Sun Nov 9 22:11:37 2014 +0100 + + Removed erroneous backslash in documentation + +M Documentation/SOGoInstallationGuide.asciidoc + +commit 3d18c94789235c50a8028d209b5cbf0203cb5dce +Author: Francis Lachapelle +Date: Mon Nov 17 14:24:14 2014 -0500 + + Fix extraction of email addresses in some cases + + Fixes #2945 + +M NEWS +M UI/WebServerResources/UIxMailToSelection.js + +commit 1f167d9e821e5d4b54323c048e744c657dc4dd48 +Author: Ludovic Marcotte +Date: Mon Nov 17 11:49:56 2014 -0500 + + Fixed IMAP searches with non-ASCII folder names + +M NEWS +M UI/MailerUI/UIxMailSearch.m +M UI/Templates/MailerUI/UIxMailSearch.wox +M UI/WebServerResources/UIxMailSearch.js + +commit 3872341a85c4e54a5671bde5e414c58c1ebca19e +Author: Ludovic Marcotte +Date: Fri Nov 14 10:34:36 2014 -0500 + + Added required patch for previous commit + +M SoObjects/SOGo/SOGoGCSFolder.m + +commit b3cd609ae76414237db120fd76545afe11f6346b +Author: Ludovic Marcotte +Date: Fri Nov 14 09:13:14 2014 -0500 + + Added WindowSize support for GCS collections + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M NEWS + +commit c0f0f2023c09352179251c9158d9014d9fab55a7 +Author: Ludovic Marcotte +Date: Wed Nov 12 15:09:26 2014 -0500 + + added NEWS entry for BSON goodie + +M NEWS + +commit ea43f4a635124fc012f994a02b95a9f277d4345e +Author: Ludovic Marcotte +Date: Wed Nov 12 15:05:05 2014 -0500 + + Comment improvement + +M ActiveSync/SOGoActiveSyncDispatcher.m + +commit d25fe1a58b23e012e83b52979ce98020b4bd5f63 +Author: Ludovic Marcotte +Date: Wed Nov 12 14:57:54 2014 -0500 + + Dramatically improved BSON deserialization speed by avoiding tz name lookups + +M SoObjects/SOGo/BSONCodec.m + +commit 8e1dc0ecb06b899b20336bb2928050f93c80fc5a +Author: Ludovic Marcotte +Date: Wed Nov 12 12:56:34 2014 -0500 + + Typo in previous commit + +M packaging/rhel/sogo.spec + +commit 715999edc80fa434f2bf882e666a47111c5d2c39 +Author: Ludovic Marcotte +Date: Wed Nov 12 12:54:07 2014 -0500 + + Avoid compilation failures on non-RHEL 7 distros + +M packaging/rhel/sogo.spec + +commit c159d5461bbb26edbe8485ca4461de62f008107c +Author: Ludovic Marcotte +Date: Wed Nov 12 10:02:04 2014 -0500 + + disable rpm-check-build for now + +M packaging/rhel/sogo.spec + +commit 5284b57340d917417ed489875cffbdc5fcbb00e7 +Author: Ludovic Marcotte +Date: Mon Nov 10 16:19:10 2014 -0500 + + More EL7 fixes + +M packaging/rhel/sogo.spec + +commit d8e6447fcc6f41687668fdd3649f4b58478bdcff +Author: Ludovic Marcotte +Date: Mon Nov 10 16:17:06 2014 -0500 + + More disable lasso + +M packaging/rhel/sogo.spec + +commit cb8b0b028ed852bc0877237bf76296ee17aaa1d8 +Author: Ludovic Marcotte +Date: Mon Nov 10 16:15:05 2014 -0500 + + Disable lasso for RHEL7 for now + +M packaging/rhel/sogo.spec + +commit df648c920467773b0871fde538f5003113ca7aab +Author: Francis Lachapelle +Date: Mon Nov 10 13:51:38 2014 -0500 + + Add 'zip' to packages dependencies + + Fixes #2963 + +M packaging/debian-multiarch/control +M packaging/debian/control +M packaging/rhel/sogo.spec + +commit 624af1c0fb494abbf16fc4b8620b13f5e3bf4e7c +Author: Ludovic Marcotte +Date: Mon Nov 10 08:58:30 2014 -0500 + + Fixed test + +M Tests/Integration/test-davacl.py + +commit 395a8ddcfefbd0a897274aa278f30c3fc545f4ac +Author: Ludovic Marcotte +Date: Fri Nov 7 10:36:11 2014 -0500 + + Updated once more the tz and added missing zones + +M SOPE/NGCards/TimeZones/America/Grand_Turk.ics +M SOPE/NGCards/TimeZones/America/Metlakatla.ics +M SOPE/NGCards/TimeZones/Antarctica/Casey.ics +A SOPE/NGCards/TimeZones/Asia/Chita.ics +M SOPE/NGCards/TimeZones/Asia/Irkutsk.ics +M SOPE/NGCards/TimeZones/Asia/Khandyga.ics +M SOPE/NGCards/TimeZones/Asia/Krasnoyarsk.ics +M SOPE/NGCards/TimeZones/Asia/Magadan.ics +M SOPE/NGCards/TimeZones/Asia/Novokuznetsk.ics +M SOPE/NGCards/TimeZones/Asia/Novosibirsk.ics +M SOPE/NGCards/TimeZones/Asia/Omsk.ics +M SOPE/NGCards/TimeZones/Asia/Sakhalin.ics +A SOPE/NGCards/TimeZones/Asia/Srednekolymsk.ics +M SOPE/NGCards/TimeZones/Asia/Urumqi.ics +M SOPE/NGCards/TimeZones/Asia/Ust-Nera.ics +M SOPE/NGCards/TimeZones/Asia/Vladivostok.ics +M SOPE/NGCards/TimeZones/Asia/Yakutsk.ics +M SOPE/NGCards/TimeZones/Asia/Yekaterinburg.ics +M SOPE/NGCards/TimeZones/Australia/Adelaide.ics +M SOPE/NGCards/TimeZones/Australia/Brisbane.ics +M SOPE/NGCards/TimeZones/Australia/Broken_Hill.ics +M SOPE/NGCards/TimeZones/Australia/Currie.ics +M SOPE/NGCards/TimeZones/Australia/Darwin.ics +M SOPE/NGCards/TimeZones/Australia/Eucla.ics +M SOPE/NGCards/TimeZones/Australia/Hobart.ics +M SOPE/NGCards/TimeZones/Australia/Lindeman.ics +M SOPE/NGCards/TimeZones/Australia/Lord_Howe.ics +M SOPE/NGCards/TimeZones/Australia/Melbourne.ics +M SOPE/NGCards/TimeZones/Australia/Perth.ics +M SOPE/NGCards/TimeZones/Australia/Sydney.ics +M SOPE/NGCards/TimeZones/Europe/Kaliningrad.ics +M SOPE/NGCards/TimeZones/Europe/Minsk.ics +M SOPE/NGCards/TimeZones/Europe/Moscow.ics +M SOPE/NGCards/TimeZones/Europe/Simferopol.ics +M SOPE/NGCards/TimeZones/Europe/Volgograd.ics +M SOPE/NGCards/TimeZones/Pacific/Apia.ics +A SOPE/NGCards/TimeZones/Pacific/Bougainville.ics +M SOPE/NGCards/TimeZones/Pacific/Fiji.ics +M SOPE/NGCards/TimeZones/UPDATING + +commit 8cd72a8fda714f62d0a62cee5bb22ac4986ecfef +Author: Ludovic Marcotte +Date: Fri Nov 7 10:06:53 2014 -0500 + + Fix borken ORGANIZER fields during the PUT action + +M SoObjects/Appointments/SOGoAppointmentObject.m + +commit 11a4c1358d6c1b9f6e5bb0fef63572a90d34ff16 +Author: Ludovic Marcotte +Date: Thu Nov 6 11:23:34 2014 -0500 + + Fixed corrupted PNG files (#2975) + +M NEWS +M UI/WebServerResources/arrow-left.png +M UI/WebServerResources/arrow-right.png +M UI/WebServerResources/minus.png +M UI/WebServerResources/plus.png + +commit 54d8aa88870f585ba9bb6422ed7dc68d8a980ea5 +Author: Ludovic Marcotte +Date: Thu Nov 6 11:10:31 2014 -0500 + + Added new zone files + +A SOPE/NGCards/TimeZones/Antarctica/Troll.ics +A SOPE/NGCards/TimeZones/Asia/Khandyga.ics +A SOPE/NGCards/TimeZones/Asia/Ust-Nera.ics +A SOPE/NGCards/TimeZones/Europe/Busingen.ics + +commit 49da494260949c1f6fe022e9825f026241f0f1c1 +Author: Ludovic Marcotte +Date: Thu Nov 6 11:09:16 2014 -0500 + + Fix for bug #2968 + +M NEWS +M SOPE/NGCards/TimeZones/Africa/Abidjan.ics +M SOPE/NGCards/TimeZones/Africa/Accra.ics +M SOPE/NGCards/TimeZones/Africa/Addis_Ababa.ics +M SOPE/NGCards/TimeZones/Africa/Algiers.ics +M SOPE/NGCards/TimeZones/Africa/Asmara.ics +M SOPE/NGCards/TimeZones/Africa/Bamako.ics +M SOPE/NGCards/TimeZones/Africa/Bangui.ics +M SOPE/NGCards/TimeZones/Africa/Banjul.ics +M SOPE/NGCards/TimeZones/Africa/Bissau.ics +M SOPE/NGCards/TimeZones/Africa/Blantyre.ics +M SOPE/NGCards/TimeZones/Africa/Brazzaville.ics +M SOPE/NGCards/TimeZones/Africa/Bujumbura.ics +M SOPE/NGCards/TimeZones/Africa/Cairo.ics +M SOPE/NGCards/TimeZones/Africa/Casablanca.ics +M SOPE/NGCards/TimeZones/Africa/Ceuta.ics +M SOPE/NGCards/TimeZones/Africa/Conakry.ics +M SOPE/NGCards/TimeZones/Africa/Dakar.ics +M SOPE/NGCards/TimeZones/Africa/Dar_es_Salaam.ics +M SOPE/NGCards/TimeZones/Africa/Djibouti.ics +M SOPE/NGCards/TimeZones/Africa/Douala.ics +M SOPE/NGCards/TimeZones/Africa/El_Aaiun.ics +M SOPE/NGCards/TimeZones/Africa/Freetown.ics +M SOPE/NGCards/TimeZones/Africa/Gaborone.ics +M SOPE/NGCards/TimeZones/Africa/Harare.ics +M SOPE/NGCards/TimeZones/Africa/Johannesburg.ics +M SOPE/NGCards/TimeZones/Africa/Juba.ics +M SOPE/NGCards/TimeZones/Africa/Kampala.ics +M SOPE/NGCards/TimeZones/Africa/Khartoum.ics +M SOPE/NGCards/TimeZones/Africa/Kigali.ics +M SOPE/NGCards/TimeZones/Africa/Kinshasa.ics +M SOPE/NGCards/TimeZones/Africa/Lagos.ics +M SOPE/NGCards/TimeZones/Africa/Libreville.ics +M SOPE/NGCards/TimeZones/Africa/Lome.ics +M SOPE/NGCards/TimeZones/Africa/Luanda.ics +M SOPE/NGCards/TimeZones/Africa/Lubumbashi.ics +M SOPE/NGCards/TimeZones/Africa/Lusaka.ics +M SOPE/NGCards/TimeZones/Africa/Malabo.ics +M SOPE/NGCards/TimeZones/Africa/Maputo.ics +M SOPE/NGCards/TimeZones/Africa/Maseru.ics +M SOPE/NGCards/TimeZones/Africa/Mbabane.ics +M SOPE/NGCards/TimeZones/Africa/Mogadishu.ics +M SOPE/NGCards/TimeZones/Africa/Monrovia.ics +M SOPE/NGCards/TimeZones/Africa/Nairobi.ics +M SOPE/NGCards/TimeZones/Africa/Ndjamena.ics +M SOPE/NGCards/TimeZones/Africa/Niamey.ics +M SOPE/NGCards/TimeZones/Africa/Nouakchott.ics +M SOPE/NGCards/TimeZones/Africa/Ouagadougou.ics +M SOPE/NGCards/TimeZones/Africa/Porto-Novo.ics +M SOPE/NGCards/TimeZones/Africa/Sao_Tome.ics +M SOPE/NGCards/TimeZones/Africa/Tripoli.ics +M SOPE/NGCards/TimeZones/Africa/Tunis.ics +M SOPE/NGCards/TimeZones/Africa/Windhoek.ics +M SOPE/NGCards/TimeZones/America/Adak.ics +M SOPE/NGCards/TimeZones/America/Anchorage.ics +M SOPE/NGCards/TimeZones/America/Anguilla.ics +M SOPE/NGCards/TimeZones/America/Antigua.ics +M SOPE/NGCards/TimeZones/America/Araguaina.ics +M SOPE/NGCards/TimeZones/America/Argentina/Buenos_Aires.ics +M SOPE/NGCards/TimeZones/America/Argentina/Catamarca.ics +M SOPE/NGCards/TimeZones/America/Argentina/Cordoba.ics +M SOPE/NGCards/TimeZones/America/Argentina/Jujuy.ics +M SOPE/NGCards/TimeZones/America/Argentina/La_Rioja.ics +M SOPE/NGCards/TimeZones/America/Argentina/Mendoza.ics +M SOPE/NGCards/TimeZones/America/Argentina/Rio_Gallegos.ics +M SOPE/NGCards/TimeZones/America/Argentina/Salta.ics +M SOPE/NGCards/TimeZones/America/Argentina/San_Juan.ics +M SOPE/NGCards/TimeZones/America/Argentina/San_Luis.ics +M SOPE/NGCards/TimeZones/America/Argentina/Tucuman.ics +M SOPE/NGCards/TimeZones/America/Argentina/Ushuaia.ics +M SOPE/NGCards/TimeZones/America/Aruba.ics +M SOPE/NGCards/TimeZones/America/Asuncion.ics +M SOPE/NGCards/TimeZones/America/Atikokan.ics +M SOPE/NGCards/TimeZones/America/Bahia.ics +M SOPE/NGCards/TimeZones/America/Bahia_Banderas.ics +M SOPE/NGCards/TimeZones/America/Barbados.ics +M SOPE/NGCards/TimeZones/America/Belem.ics +M SOPE/NGCards/TimeZones/America/Belize.ics +M SOPE/NGCards/TimeZones/America/Blanc-Sablon.ics +M SOPE/NGCards/TimeZones/America/Boa_Vista.ics +M SOPE/NGCards/TimeZones/America/Bogota.ics +M SOPE/NGCards/TimeZones/America/Boise.ics +M SOPE/NGCards/TimeZones/America/Cambridge_Bay.ics +M SOPE/NGCards/TimeZones/America/Campo_Grande.ics +M SOPE/NGCards/TimeZones/America/Cancun.ics +M SOPE/NGCards/TimeZones/America/Caracas.ics +M SOPE/NGCards/TimeZones/America/Cayenne.ics +M SOPE/NGCards/TimeZones/America/Cayman.ics +M SOPE/NGCards/TimeZones/America/Chicago.ics +M SOPE/NGCards/TimeZones/America/Chihuahua.ics +M SOPE/NGCards/TimeZones/America/Costa_Rica.ics +M SOPE/NGCards/TimeZones/America/Creston.ics +M SOPE/NGCards/TimeZones/America/Cuiaba.ics +M SOPE/NGCards/TimeZones/America/Curacao.ics +M SOPE/NGCards/TimeZones/America/Danmarkshavn.ics +M SOPE/NGCards/TimeZones/America/Dawson.ics +M SOPE/NGCards/TimeZones/America/Dawson_Creek.ics +M SOPE/NGCards/TimeZones/America/Denver.ics +M SOPE/NGCards/TimeZones/America/Detroit.ics +M SOPE/NGCards/TimeZones/America/Dominica.ics +M SOPE/NGCards/TimeZones/America/Edmonton.ics +M SOPE/NGCards/TimeZones/America/Eirunepe.ics +M SOPE/NGCards/TimeZones/America/El_Salvador.ics +M SOPE/NGCards/TimeZones/America/Fortaleza.ics +M SOPE/NGCards/TimeZones/America/Glace_Bay.ics +M SOPE/NGCards/TimeZones/America/Godthab.ics +M SOPE/NGCards/TimeZones/America/Goose_Bay.ics +M SOPE/NGCards/TimeZones/America/Grand_Turk.ics +M SOPE/NGCards/TimeZones/America/Grenada.ics +M SOPE/NGCards/TimeZones/America/Guadeloupe.ics +M SOPE/NGCards/TimeZones/America/Guatemala.ics +M SOPE/NGCards/TimeZones/America/Guayaquil.ics +M SOPE/NGCards/TimeZones/America/Guyana.ics +M SOPE/NGCards/TimeZones/America/Halifax.ics +M SOPE/NGCards/TimeZones/America/Havana.ics +M SOPE/NGCards/TimeZones/America/Hermosillo.ics +M SOPE/NGCards/TimeZones/America/Indiana/Indianapolis.ics +M SOPE/NGCards/TimeZones/America/Indiana/Knox.ics +M SOPE/NGCards/TimeZones/America/Indiana/Marengo.ics +M SOPE/NGCards/TimeZones/America/Indiana/Petersburg.ics +M SOPE/NGCards/TimeZones/America/Indiana/Tell_City.ics +M SOPE/NGCards/TimeZones/America/Indiana/Vevay.ics +M SOPE/NGCards/TimeZones/America/Indiana/Vincennes.ics +M SOPE/NGCards/TimeZones/America/Indiana/Winamac.ics +M SOPE/NGCards/TimeZones/America/Inuvik.ics +M SOPE/NGCards/TimeZones/America/Iqaluit.ics +M SOPE/NGCards/TimeZones/America/Jamaica.ics +M SOPE/NGCards/TimeZones/America/Juneau.ics +M SOPE/NGCards/TimeZones/America/Kentucky/Louisville.ics +M SOPE/NGCards/TimeZones/America/Kentucky/Monticello.ics +M SOPE/NGCards/TimeZones/America/Kralendijk.ics +M SOPE/NGCards/TimeZones/America/La_Paz.ics +M SOPE/NGCards/TimeZones/America/Lima.ics +M SOPE/NGCards/TimeZones/America/Los_Angeles.ics +M SOPE/NGCards/TimeZones/America/Lower_Princes.ics +M SOPE/NGCards/TimeZones/America/Maceio.ics +M SOPE/NGCards/TimeZones/America/Managua.ics +M SOPE/NGCards/TimeZones/America/Manaus.ics +M SOPE/NGCards/TimeZones/America/Marigot.ics +M SOPE/NGCards/TimeZones/America/Martinique.ics +M SOPE/NGCards/TimeZones/America/Matamoros.ics +M SOPE/NGCards/TimeZones/America/Mazatlan.ics +M SOPE/NGCards/TimeZones/America/Menominee.ics +M SOPE/NGCards/TimeZones/America/Merida.ics +M SOPE/NGCards/TimeZones/America/Metlakatla.ics +M SOPE/NGCards/TimeZones/America/Mexico_City.ics +M SOPE/NGCards/TimeZones/America/Miquelon.ics +M SOPE/NGCards/TimeZones/America/Moncton.ics +M SOPE/NGCards/TimeZones/America/Monterrey.ics +M SOPE/NGCards/TimeZones/America/Montevideo.ics +M SOPE/NGCards/TimeZones/America/Montreal.ics +M SOPE/NGCards/TimeZones/America/Montserrat.ics +M SOPE/NGCards/TimeZones/America/Nassau.ics +M SOPE/NGCards/TimeZones/America/New_York.ics +M SOPE/NGCards/TimeZones/America/Nipigon.ics +M SOPE/NGCards/TimeZones/America/Nome.ics +M SOPE/NGCards/TimeZones/America/Noronha.ics +M SOPE/NGCards/TimeZones/America/North_Dakota/Beulah.ics +M SOPE/NGCards/TimeZones/America/North_Dakota/Center.ics +M SOPE/NGCards/TimeZones/America/North_Dakota/New_Salem.ics +M SOPE/NGCards/TimeZones/America/Ojinaga.ics +M SOPE/NGCards/TimeZones/America/Panama.ics +M SOPE/NGCards/TimeZones/America/Pangnirtung.ics +M SOPE/NGCards/TimeZones/America/Paramaribo.ics +M SOPE/NGCards/TimeZones/America/Phoenix.ics +M SOPE/NGCards/TimeZones/America/Port-au-Prince.ics +M SOPE/NGCards/TimeZones/America/Port_of_Spain.ics +M SOPE/NGCards/TimeZones/America/Porto_Velho.ics +M SOPE/NGCards/TimeZones/America/Puerto_Rico.ics +M SOPE/NGCards/TimeZones/America/Rainy_River.ics +M SOPE/NGCards/TimeZones/America/Rankin_Inlet.ics +M SOPE/NGCards/TimeZones/America/Recife.ics +M SOPE/NGCards/TimeZones/America/Regina.ics +M SOPE/NGCards/TimeZones/America/Resolute.ics +M SOPE/NGCards/TimeZones/America/Rio_Branco.ics +M SOPE/NGCards/TimeZones/America/Santa_Isabel.ics +M SOPE/NGCards/TimeZones/America/Santarem.ics +M SOPE/NGCards/TimeZones/America/Santiago.ics +M SOPE/NGCards/TimeZones/America/Santo_Domingo.ics +M SOPE/NGCards/TimeZones/America/Sao_Paulo.ics +M SOPE/NGCards/TimeZones/America/Scoresbysund.ics +M SOPE/NGCards/TimeZones/America/Sitka.ics +M SOPE/NGCards/TimeZones/America/St_Barthelemy.ics +M SOPE/NGCards/TimeZones/America/St_Johns.ics +M SOPE/NGCards/TimeZones/America/St_Kitts.ics +M SOPE/NGCards/TimeZones/America/St_Lucia.ics +M SOPE/NGCards/TimeZones/America/St_Thomas.ics +M SOPE/NGCards/TimeZones/America/St_Vincent.ics +M SOPE/NGCards/TimeZones/America/Swift_Current.ics +M SOPE/NGCards/TimeZones/America/Tegucigalpa.ics +M SOPE/NGCards/TimeZones/America/Thule.ics +M SOPE/NGCards/TimeZones/America/Thunder_Bay.ics +M SOPE/NGCards/TimeZones/America/Tijuana.ics +M SOPE/NGCards/TimeZones/America/Toronto.ics +M SOPE/NGCards/TimeZones/America/Tortola.ics +M SOPE/NGCards/TimeZones/America/Vancouver.ics +M SOPE/NGCards/TimeZones/America/Whitehorse.ics +M SOPE/NGCards/TimeZones/America/Winnipeg.ics +M SOPE/NGCards/TimeZones/America/Yakutat.ics +M SOPE/NGCards/TimeZones/America/Yellowknife.ics +M SOPE/NGCards/TimeZones/Antarctica/Casey.ics +M SOPE/NGCards/TimeZones/Antarctica/Davis.ics +M SOPE/NGCards/TimeZones/Antarctica/DumontDUrville.ics +M SOPE/NGCards/TimeZones/Antarctica/Macquarie.ics +M SOPE/NGCards/TimeZones/Antarctica/Mawson.ics +M SOPE/NGCards/TimeZones/Antarctica/McMurdo.ics +M SOPE/NGCards/TimeZones/Antarctica/Palmer.ics +M SOPE/NGCards/TimeZones/Antarctica/Rothera.ics +M SOPE/NGCards/TimeZones/Antarctica/Syowa.ics +M SOPE/NGCards/TimeZones/Antarctica/Vostok.ics +M SOPE/NGCards/TimeZones/Arctic/Longyearbyen.ics +M SOPE/NGCards/TimeZones/Asia/Aden.ics +M SOPE/NGCards/TimeZones/Asia/Almaty.ics +M SOPE/NGCards/TimeZones/Asia/Amman.ics +M SOPE/NGCards/TimeZones/Asia/Anadyr.ics +M SOPE/NGCards/TimeZones/Asia/Aqtau.ics +M SOPE/NGCards/TimeZones/Asia/Aqtobe.ics +M SOPE/NGCards/TimeZones/Asia/Ashgabat.ics +M SOPE/NGCards/TimeZones/Asia/Baghdad.ics +M SOPE/NGCards/TimeZones/Asia/Bahrain.ics +M SOPE/NGCards/TimeZones/Asia/Baku.ics +M SOPE/NGCards/TimeZones/Asia/Bangkok.ics +M SOPE/NGCards/TimeZones/Asia/Beirut.ics +M SOPE/NGCards/TimeZones/Asia/Bishkek.ics +M SOPE/NGCards/TimeZones/Asia/Brunei.ics +M SOPE/NGCards/TimeZones/Asia/Choibalsan.ics +M SOPE/NGCards/TimeZones/Asia/Chongqing.ics +M SOPE/NGCards/TimeZones/Asia/Colombo.ics +M SOPE/NGCards/TimeZones/Asia/Damascus.ics +M SOPE/NGCards/TimeZones/Asia/Dhaka.ics +M SOPE/NGCards/TimeZones/Asia/Dili.ics +M SOPE/NGCards/TimeZones/Asia/Dubai.ics +M SOPE/NGCards/TimeZones/Asia/Dushanbe.ics +M SOPE/NGCards/TimeZones/Asia/Gaza.ics +M SOPE/NGCards/TimeZones/Asia/Harbin.ics +M SOPE/NGCards/TimeZones/Asia/Hebron.ics +M SOPE/NGCards/TimeZones/Asia/Ho_Chi_Minh.ics +M SOPE/NGCards/TimeZones/Asia/Hong_Kong.ics +M SOPE/NGCards/TimeZones/Asia/Hovd.ics +M SOPE/NGCards/TimeZones/Asia/Irkutsk.ics +M SOPE/NGCards/TimeZones/Asia/Istanbul.ics +M SOPE/NGCards/TimeZones/Asia/Jakarta.ics +M SOPE/NGCards/TimeZones/Asia/Jayapura.ics +M SOPE/NGCards/TimeZones/Asia/Jerusalem.ics +M SOPE/NGCards/TimeZones/Asia/Kabul.ics +M SOPE/NGCards/TimeZones/Asia/Kamchatka.ics +M SOPE/NGCards/TimeZones/Asia/Karachi.ics +M SOPE/NGCards/TimeZones/Asia/Kashgar.ics +M SOPE/NGCards/TimeZones/Asia/Kathmandu.ics +M SOPE/NGCards/TimeZones/Asia/Kolkata.ics +M SOPE/NGCards/TimeZones/Asia/Krasnoyarsk.ics +M SOPE/NGCards/TimeZones/Asia/Kuala_Lumpur.ics +M SOPE/NGCards/TimeZones/Asia/Kuching.ics +M SOPE/NGCards/TimeZones/Asia/Kuwait.ics +M SOPE/NGCards/TimeZones/Asia/Macau.ics +M SOPE/NGCards/TimeZones/Asia/Magadan.ics +M SOPE/NGCards/TimeZones/Asia/Makassar.ics +M SOPE/NGCards/TimeZones/Asia/Manila.ics +M SOPE/NGCards/TimeZones/Asia/Muscat.ics +M SOPE/NGCards/TimeZones/Asia/Nicosia.ics +M SOPE/NGCards/TimeZones/Asia/Novokuznetsk.ics +M SOPE/NGCards/TimeZones/Asia/Novosibirsk.ics +M SOPE/NGCards/TimeZones/Asia/Omsk.ics +M SOPE/NGCards/TimeZones/Asia/Oral.ics +M SOPE/NGCards/TimeZones/Asia/Phnom_Penh.ics +M SOPE/NGCards/TimeZones/Asia/Pontianak.ics +M SOPE/NGCards/TimeZones/Asia/Pyongyang.ics +M SOPE/NGCards/TimeZones/Asia/Qatar.ics +M SOPE/NGCards/TimeZones/Asia/Qyzylorda.ics +M SOPE/NGCards/TimeZones/Asia/Rangoon.ics +M SOPE/NGCards/TimeZones/Asia/Riyadh.ics +M SOPE/NGCards/TimeZones/Asia/Sakhalin.ics +M SOPE/NGCards/TimeZones/Asia/Samarkand.ics +M SOPE/NGCards/TimeZones/Asia/Seoul.ics +M SOPE/NGCards/TimeZones/Asia/Shanghai.ics +M SOPE/NGCards/TimeZones/Asia/Singapore.ics +M SOPE/NGCards/TimeZones/Asia/Taipei.ics +M SOPE/NGCards/TimeZones/Asia/Tashkent.ics +M SOPE/NGCards/TimeZones/Asia/Tbilisi.ics +M SOPE/NGCards/TimeZones/Asia/Tehran.ics +M SOPE/NGCards/TimeZones/Asia/Thimphu.ics +M SOPE/NGCards/TimeZones/Asia/Tokyo.ics +M SOPE/NGCards/TimeZones/Asia/Ulaanbaatar.ics +M SOPE/NGCards/TimeZones/Asia/Urumqi.ics +M SOPE/NGCards/TimeZones/Asia/Vientiane.ics +M SOPE/NGCards/TimeZones/Asia/Vladivostok.ics +M SOPE/NGCards/TimeZones/Asia/Yakutsk.ics +M SOPE/NGCards/TimeZones/Asia/Yekaterinburg.ics +M SOPE/NGCards/TimeZones/Asia/Yerevan.ics +M SOPE/NGCards/TimeZones/Atlantic/Azores.ics +M SOPE/NGCards/TimeZones/Atlantic/Bermuda.ics +M SOPE/NGCards/TimeZones/Atlantic/Canary.ics +M SOPE/NGCards/TimeZones/Atlantic/Cape_Verde.ics +M SOPE/NGCards/TimeZones/Atlantic/Faroe.ics +M SOPE/NGCards/TimeZones/Atlantic/Madeira.ics +M SOPE/NGCards/TimeZones/Atlantic/Reykjavik.ics +M SOPE/NGCards/TimeZones/Atlantic/South_Georgia.ics +M SOPE/NGCards/TimeZones/Atlantic/St_Helena.ics +M SOPE/NGCards/TimeZones/Atlantic/Stanley.ics +M SOPE/NGCards/TimeZones/Australia/Adelaide.ics +M SOPE/NGCards/TimeZones/Australia/Brisbane.ics +M SOPE/NGCards/TimeZones/Australia/Broken_Hill.ics +M SOPE/NGCards/TimeZones/Australia/Currie.ics +M SOPE/NGCards/TimeZones/Australia/Darwin.ics +M SOPE/NGCards/TimeZones/Australia/Eucla.ics +M SOPE/NGCards/TimeZones/Australia/Hobart.ics +M SOPE/NGCards/TimeZones/Australia/Lindeman.ics +M SOPE/NGCards/TimeZones/Australia/Lord_Howe.ics +M SOPE/NGCards/TimeZones/Australia/Melbourne.ics +M SOPE/NGCards/TimeZones/Australia/Perth.ics +M SOPE/NGCards/TimeZones/Australia/Sydney.ics +M SOPE/NGCards/TimeZones/Europe/Amsterdam.ics +M SOPE/NGCards/TimeZones/Europe/Andorra.ics +M SOPE/NGCards/TimeZones/Europe/Athens.ics +M SOPE/NGCards/TimeZones/Europe/Belgrade.ics +M SOPE/NGCards/TimeZones/Europe/Berlin.ics +M SOPE/NGCards/TimeZones/Europe/Bratislava.ics +M SOPE/NGCards/TimeZones/Europe/Brussels.ics +M SOPE/NGCards/TimeZones/Europe/Bucharest.ics +M SOPE/NGCards/TimeZones/Europe/Budapest.ics +M SOPE/NGCards/TimeZones/Europe/Chisinau.ics +M SOPE/NGCards/TimeZones/Europe/Copenhagen.ics +M SOPE/NGCards/TimeZones/Europe/Dublin.ics +M SOPE/NGCards/TimeZones/Europe/Gibraltar.ics +M SOPE/NGCards/TimeZones/Europe/Guernsey.ics +M SOPE/NGCards/TimeZones/Europe/Helsinki.ics +M SOPE/NGCards/TimeZones/Europe/Isle_of_Man.ics +M SOPE/NGCards/TimeZones/Europe/Istanbul.ics +M SOPE/NGCards/TimeZones/Europe/Jersey.ics +M SOPE/NGCards/TimeZones/Europe/Kaliningrad.ics +M SOPE/NGCards/TimeZones/Europe/Kiev.ics +M SOPE/NGCards/TimeZones/Europe/Lisbon.ics +M SOPE/NGCards/TimeZones/Europe/Ljubljana.ics +M SOPE/NGCards/TimeZones/Europe/London.ics +M SOPE/NGCards/TimeZones/Europe/Luxembourg.ics +M SOPE/NGCards/TimeZones/Europe/Madrid.ics +M SOPE/NGCards/TimeZones/Europe/Malta.ics +M SOPE/NGCards/TimeZones/Europe/Mariehamn.ics +M SOPE/NGCards/TimeZones/Europe/Minsk.ics +M SOPE/NGCards/TimeZones/Europe/Monaco.ics +M SOPE/NGCards/TimeZones/Europe/Moscow.ics +M SOPE/NGCards/TimeZones/Europe/Nicosia.ics +M SOPE/NGCards/TimeZones/Europe/Oslo.ics +M SOPE/NGCards/TimeZones/Europe/Paris.ics +M SOPE/NGCards/TimeZones/Europe/Podgorica.ics +M SOPE/NGCards/TimeZones/Europe/Prague.ics +M SOPE/NGCards/TimeZones/Europe/Riga.ics +M SOPE/NGCards/TimeZones/Europe/Rome.ics +M SOPE/NGCards/TimeZones/Europe/Samara.ics +M SOPE/NGCards/TimeZones/Europe/San_Marino.ics +M SOPE/NGCards/TimeZones/Europe/Sarajevo.ics +M SOPE/NGCards/TimeZones/Europe/Simferopol.ics +M SOPE/NGCards/TimeZones/Europe/Skopje.ics +M SOPE/NGCards/TimeZones/Europe/Sofia.ics +M SOPE/NGCards/TimeZones/Europe/Stockholm.ics +M SOPE/NGCards/TimeZones/Europe/Tallinn.ics +M SOPE/NGCards/TimeZones/Europe/Tirane.ics +M SOPE/NGCards/TimeZones/Europe/Uzhgorod.ics +M SOPE/NGCards/TimeZones/Europe/Vaduz.ics +M SOPE/NGCards/TimeZones/Europe/Vatican.ics +M SOPE/NGCards/TimeZones/Europe/Vienna.ics +M SOPE/NGCards/TimeZones/Europe/Vilnius.ics +M SOPE/NGCards/TimeZones/Europe/Volgograd.ics +M SOPE/NGCards/TimeZones/Europe/Warsaw.ics +M SOPE/NGCards/TimeZones/Europe/Zagreb.ics +M SOPE/NGCards/TimeZones/Europe/Zaporozhye.ics +M SOPE/NGCards/TimeZones/Europe/Zurich.ics +M SOPE/NGCards/TimeZones/Indian/Antananarivo.ics +M SOPE/NGCards/TimeZones/Indian/Chagos.ics +M SOPE/NGCards/TimeZones/Indian/Christmas.ics +M SOPE/NGCards/TimeZones/Indian/Cocos.ics +M SOPE/NGCards/TimeZones/Indian/Comoro.ics +M SOPE/NGCards/TimeZones/Indian/Kerguelen.ics +M SOPE/NGCards/TimeZones/Indian/Mahe.ics +M SOPE/NGCards/TimeZones/Indian/Maldives.ics +M SOPE/NGCards/TimeZones/Indian/Mauritius.ics +M SOPE/NGCards/TimeZones/Indian/Mayotte.ics +M SOPE/NGCards/TimeZones/Indian/Reunion.ics +M SOPE/NGCards/TimeZones/Pacific/Apia.ics +M SOPE/NGCards/TimeZones/Pacific/Auckland.ics +M SOPE/NGCards/TimeZones/Pacific/Chatham.ics +M SOPE/NGCards/TimeZones/Pacific/Chuuk.ics +M SOPE/NGCards/TimeZones/Pacific/Easter.ics +M SOPE/NGCards/TimeZones/Pacific/Efate.ics +M SOPE/NGCards/TimeZones/Pacific/Enderbury.ics +M SOPE/NGCards/TimeZones/Pacific/Fakaofo.ics +M SOPE/NGCards/TimeZones/Pacific/Fiji.ics +M SOPE/NGCards/TimeZones/Pacific/Funafuti.ics +M SOPE/NGCards/TimeZones/Pacific/Galapagos.ics +M SOPE/NGCards/TimeZones/Pacific/Gambier.ics +M SOPE/NGCards/TimeZones/Pacific/Guadalcanal.ics +M SOPE/NGCards/TimeZones/Pacific/Guam.ics +M SOPE/NGCards/TimeZones/Pacific/Honolulu.ics +M SOPE/NGCards/TimeZones/Pacific/Johnston.ics +M SOPE/NGCards/TimeZones/Pacific/Kiritimati.ics +M SOPE/NGCards/TimeZones/Pacific/Kosrae.ics +M SOPE/NGCards/TimeZones/Pacific/Kwajalein.ics +M SOPE/NGCards/TimeZones/Pacific/Majuro.ics +M SOPE/NGCards/TimeZones/Pacific/Marquesas.ics +M SOPE/NGCards/TimeZones/Pacific/Midway.ics +M SOPE/NGCards/TimeZones/Pacific/Nauru.ics +M SOPE/NGCards/TimeZones/Pacific/Niue.ics +M SOPE/NGCards/TimeZones/Pacific/Norfolk.ics +M SOPE/NGCards/TimeZones/Pacific/Noumea.ics +M SOPE/NGCards/TimeZones/Pacific/Pago_Pago.ics +M SOPE/NGCards/TimeZones/Pacific/Palau.ics +M SOPE/NGCards/TimeZones/Pacific/Pitcairn.ics +M SOPE/NGCards/TimeZones/Pacific/Pohnpei.ics +M SOPE/NGCards/TimeZones/Pacific/Port_Moresby.ics +M SOPE/NGCards/TimeZones/Pacific/Rarotonga.ics +M SOPE/NGCards/TimeZones/Pacific/Saipan.ics +M SOPE/NGCards/TimeZones/Pacific/Tahiti.ics +M SOPE/NGCards/TimeZones/Pacific/Tarawa.ics +M SOPE/NGCards/TimeZones/Pacific/Tongatapu.ics +M SOPE/NGCards/TimeZones/Pacific/Wake.ics +M SOPE/NGCards/TimeZones/Pacific/Wallis.ics + +commit e08dd3f9eb16bdf122a398fd46a725ec33c55226 +Author: Ludovic Marcotte +Date: Thu Nov 6 10:16:47 2014 -0500 + + Fix for bug #2978 + +M ActiveSync/iCalEvent+ActiveSync.m +M NEWS + +commit 6de70e4043bc09a9182ce8a22e2c4f9a76b11af3 +Author: Ludovic Marcotte +Date: Thu Nov 6 09:35:58 2014 -0500 + + sanitize strings before encoding them when using EAS + +M ActiveSync/NSString+ActiveSync.m +M NEWS + +commit 7052daa1c8fded384e5dd9e7582014a5acd8188e +Author: Francis Lachapelle +Date: Wed Nov 5 10:02:55 2014 -0500 + + Fix rename of subscribed addressbooks + +M NEWS +M UI/Common/product.plist +M UI/WebServerResources/ContactsUI.js + +commit 15be4861b6574ce7573e2ebc6e3d3bc3fb10110f +Author: Francis Lachapelle +Date: Wed Nov 5 08:44:52 2014 -0500 + + Fix support for SieveFolderEncoding default + + Fixes #2622 + +M NEWS +M UI/PreferencesUI/UIxFilterEditor.m + +commit 4b9958336c470a00933b2786c2105a25f95f7801 +Author: Ludovic Marcotte +Date: Tue Nov 4 13:50:10 2014 -0500 + + Handle base64-encoded command parameters in EAS + +M ActiveSync/NSString+ActiveSync.m + +commit 52fdcc34de6fb482b94736652a7699436c17db82 +Author: Ludovic Marcotte +Date: Fri Oct 31 06:46:03 2014 -0400 + + Fixed typo + +M ActiveSync/iCalEvent+ActiveSync.m + +commit 08427e0bfb8bba2fd273443558a6832ac1ac0cc5 +Author: Ludovic Marcotte +Date: Thu Oct 30 18:58:52 2014 -0400 + + set userTimeZone if event has no tz + +M ActiveSync/iCalEvent+ActiveSync.m + +commit d76a4361a094c2a235e310f9e86ab38602d568f7 +Author: Ludovic Marcotte +Date: Thu Oct 30 09:20:21 2014 -0400 + + Added one more sanitization pass on decoded content + +M ActiveSync/SOGoMailObject+ActiveSync.m + +commit 70cd24e111b04a7bb598a56f86da34fefb689fbf +Author: Ludovic Marcotte +Date: Wed Oct 29 16:42:52 2014 -0400 + + Fix for bug #2965 + +M NEWS +M UI/MailerUI/UIxMailView.m + +commit b5023eeb245c0c0cec40b018af404049119cd4d0 +Author: Ludovic Marcotte +Date: Wed Oct 29 14:56:03 2014 -0400 + + Fix for bug #2940 + +M ActiveSync/SOGoActiveSyncDispatcher.m +M Documentation/SOGoInstallationGuide.asciidoc +M NEWS +M SoObjects/SOGo/SOGoSystemDefaults.m + +commit da962aed01b32be85f85483dfbe978aa4e259361 +Author: Ludovic Marcotte +Date: Wed Oct 29 14:20:03 2014 -0400 + + Added support for multiple calendars/addressbooks over ActiveSync + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m +M ActiveSync/SOGoActiveSyncDispatcher.m +M SoObjects/Mailer/SOGoMailAccount.m +M SoObjects/SOGo/SOGoCacheGCSObject.h +M SoObjects/SOGo/SOGoCacheGCSObject.m + +commit 395545ca519f4771369eca77d0d4b5aa9d79d1df +Author: Ludovic Marcotte +Date: Wed Oct 29 11:13:18 2014 -0400 + + WP fails to sync if an event is changed on the sever and the client sends a modification of another event + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m + +commit b53c7267660ba76d26f08b824b88cc87824a7cd3 +Author: Ludovic Marcotte +Date: Wed Oct 29 10:46:45 2014 -0400 + + TZ fixes on WP devices all day events + +M ActiveSync/iCalTimeZone+ActiveSync.m + +commit 6695aa083f5f315bfd95d61e7da58c261e611c3b +Author: Francis Lachapelle +Date: Fri Oct 17 15:20:25 2014 -0400 + + Fix crash when opening a mailbox with empty filter + + Fixes #2959 + +M UI/MailerUI/UIxMailListActions.m +M UI/WebServerResources/MailerUI.js + +commit 42ef0bfc3f30a4ce77fab46fd48fc197dfe37684 +Author: Ludovic Marcotte +Date: Thu Oct 16 11:49:07 2014 -0400 + + Added doc around IMAP word size vs. ActiveSync on large mail folders + +M Documentation/SOGoInstallationGuide.asciidoc + +commit fb95d84a3a4eb1c3f329a02a4496cc7528f17c2a +Author: Ludovic Marcotte +Date: Thu Oct 16 09:35:15 2014 -0400 + + Handle base64 encoded query strings, popular on Windows devices + +M ActiveSync/NSString+ActiveSync.m + +commit 231987242b367f3d60d45edf3ebddfda4257709f +Author: Ludovic Marcotte +Date: Thu Oct 16 09:10:54 2014 -0400 + + Handle empty Attendees tag + +M ActiveSync/iCalEvent+ActiveSync.m + +commit b4f7ec3708bb5c44aaf1bd6637ee1f1df9a0b783 +Author: Ludovic Marcotte +Date: Thu Oct 16 09:08:50 2014 -0400 + + Don't send empty tag + +M ActiveSync/SOGoActiveSyncDispatcher+Sync.m + +commit b2cab02d7064a6a7c79cf71a5aa748fa31be11ad +Author: Ludovic Marcotte +Date: Thu Oct 16 09:03:34 2014 -0400 + + Handle empty categories + +M ActiveSync/NGVCard+ActiveSync.m + +commit d6ff9038ce09e1c5eb507fc8d884708bc706d306 +Author: Ludovic Marcotte +Date: Thu Oct 16 09:02:18 2014 -0400 + + Disable timezone in AS for now + +M ActiveSync/iCalEvent+ActiveSync.m + +commit c43ad378500367eb1639d43ab6f69e81e13d2ff4 +Author: Ludovic Marcotte +Date: Wed Oct 15 15:21:20 2014 -0400 + + Disable OpenChange for now on RHEL 7 + +M packaging/rhel/sogo.spec + +commit 096a0ef8e4f908802176903685e74826c1fbc2ae +Author: Ludovic Marcotte +Date: Wed Oct 15 11:35:59 2014 -0400 + + Disabled openchange builds on all i386 arch + +M packaging/rhel/sogo.spec + +commit e2136e041354f27fb0938b3fad15aa999ebe0621 +Author: Francis Lachapelle +Date: Tue Oct 14 12:54:04 2014 -0400 + + Don't leak database passwords in the logs + + Fixes #2953 + +M NEWS +M SOPE/GDLContentStore/GCSChannelManager.m + +commit 3264458f4be46d8725962bb215350e7ca291ad18 +Author: Ludovic Marcotte +Date: Tue Oct 14 11:27:08 2014 -0400 + + Added back -L directives to properly compile teststrings + +M Tests/Integration/GNUmakefile.preamble + +commit 0327a42c9c7d305af78504264821281de7e9c2d3 +Author: Alexandre Cloutier +Date: Tue Oct 14 10:45:30 2014 -0400 + + Update NEWS file + +M NEWS + +commit 5f811e1a4e4e6b5e89cd616ddbc0b37ff3e0635a +Author: Ludovic Marcotte +Date: Tue Oct 14 10:43:52 2014 -0400 + + Added rpath for integration tests + +M Tests/Integration/GNUmakefile.preamble + +commit 923aa5d9b669d9ebca4b80a50c37c148aa17bb60 +Author: Alexandre Cloutier +Date: Tue Oct 14 10:29:11 2014 -0400 + + bugfix #2952, default sorting for new user + +M UI/WebServerResources/MailerUI.js + +commit 3416bfea94f17dd26b55bb4133c431f2640c9371 +Author: Ludovic Marcotte +Date: Tue Oct 14 10:00:05 2014 -0400 + + Adjusted rpath and removed unusued -L directives + +M ActiveSync/common.make +M Tools/GNUmakefile +M Tools/GNUmakefile.preamble + +commit f6639508089352980758aadc1b9d565157ee4adc +Author: Ludovic Marcotte +Date: Tue Oct 14 09:51:04 2014 -0400 + + Adjusted the rpath, removed unnecessary variables/values + +M Main/GNUmakefile +M Main/GNUmakefile.preamble + +commit ccabd93ff2175dc4c26bf11694542a1acf1d382c +Author: Ludovic Marcotte +Date: Tue Oct 14 09:21:12 2014 -0400 + + moved system lib dirs to additional lib dirs + +M Main/GNUmakefile.preamble + +commit c5a7bcf2aaa4177b873c4a0ca780e046d041e074 +Author: Ludovic Marcotte +Date: Tue Oct 14 09:17:00 2014 -0400 + + Fixed the system lib dir to point to the sogo lib dir + +M Main/GNUmakefile.preamble + +commit 81ff6bebfeb30b2abafa31eb4b0e86b102c0f4c0 +Author: Ludovic Marcotte +Date: Tue Oct 14 09:02:15 2014 -0400 + + Removed dependancies when openchange is disabled + +M packaging/rhel/sogo.spec + +commit 1a8aa5a587c63b3c5d434353a41c6d9cffd540ef +Author: Ludovic Marcotte +Date: Tue Oct 14 09:00:14 2014 -0400 + + Fixed spec file to not build sogo-openchange if disabled + +M packaging/rhel/sogo.spec + +commit 4b76e2b933ae675800139e37fdd14ad1982ebc50 +Author: Ludovic Marcotte +Date: Tue Oct 14 08:43:28 2014 -0400 + + Added lib64 in the search path + +M Tests/Integration/GNUmakefile.preamble + +commit 27ac9e3904f43de0764b426754df6c86db8f3c69 +Author: Francis Lachapelle +Date: Thu Oct 9 15:46:44 2014 -0400 + + Cleanup of unused parameters + +M SoObjects/SOGo/SOGoUserFolder.m +M UI/WebServerResources/AdministrationUI.js + +commit f8a371e351ce161037017ba79c367c494b6d56f1 +Author: Francis Lachapelle +Date: Thu Oct 9 15:12:24 2014 -0400 + + Fix folder's name when subscribing to a folder + +M NEWS +M UI/WebServerResources/UIxContactsUserFolders.js + +commit 460ed2e7bcfd11a2beef4c8146fdd9030a415115 +Author: Francis Lachapelle +Date: Thu Oct 9 15:11:06 2014 -0400 + + Fix JavaScript warning on undefined variable + +M UI/WebServerResources/ContactsUI.js + +commit 6cc8f17c86713f39ba60d8ae8129ea4ceb052f63 +Author: Francis Lachapelle +Date: Thu Oct 9 15:10:20 2014 -0400 + + Fix display name of subscribed folders + +M NEWS +M SoObjects/SOGo/SOGoGCSFolder.m + +commit ff9d49be71645c97d7692af67fda8bfacbb6179a +Author: Ludovic Marcotte +Date: Wed Oct 8 10:25:46 2014 -0400 + + Dropped rpath since it seems to be ignored on el5 + +M Tests/Integration/GNUmakefile.preamble + +commit f1919d10edcb56c4ae87a79a61522063c4d6e808 +Author: Ludovic Marcotte +Date: Wed Oct 8 09:35:50 2014 -0400 + + Flag for conditional openchange build + +M packaging/rhel/sogo.spec + +commit 3e2de9701cd1af8d27b9c0abf43e199049496b5d +Author: Ludovic Marcotte +Date: Wed Oct 8 09:29:08 2014 -0400 + + Fixes + +M packaging/rhel/sogo.spec + +commit 435ebb9eb41fc88a8af1de280f1894608e61f302 +Author: Ludovic Marcotte +Date: Wed Oct 8 09:25:40 2014 -0400 + + Fixes + +M packaging/rhel/sogo.spec + +commit ab9ba66b366c9b97cde626fe8a5cd23b3f0d3cdb +Author: Ludovic Marcotte +Date: Wed Oct 8 09:22:14 2014 -0400 + + More fixes + +M packaging/rhel/sogo.spec + +commit 29295f93c5a1b807eda1e4d6c92f9d1271e72597 +Author: Ludovic Marcotte +Date: Wed Oct 8 09:17:26 2014 -0400 + + Fixed again the spec file + +M packaging/rhel/sogo.spec + +commit 20e0cd623407d2066168818c7dd8c26a6afba05e +Author: Ludovic Marcotte +Date: Wed Oct 8 09:10:02 2014 -0400 + + Fixed RHEL packaging with lib move to "sogo" app directory + +M packaging/rhel/sogo.spec + +commit 25f68c7eb5263aaaaf7c5e4cfe29d8ecc60386ec +Author: Jens Erat +Date: Wed Oct 8 10:07:48 2014 +0200 + + Added missing NGImap4DisableIMAP4Pooling option to documentation + +M Documentation/SOGoInstallationGuide.asciidoc + +commit 22844a57426d9b3e2938a579f959fb934ef59357 +Author: Jens Erat +Date: Wed Oct 8 10:01:17 2014 +0200 + + Minor fixes in documentation + +M Documentation/SOGoInstallationGuide.asciidoc + +commit e3837188fd747ad8cb4d752c99b8027661fed03a +Author: Ludovic Marcotte +Date: Mon Oct 6 14:45:30 2014 -0400 + + Updated spec file for SOGo's private libraries move + +M packaging/rhel/sogo.spec + +commit a0317046ba4aa51450a6c9df451f322178811ff1 +Author: Francis Lachapelle +Date: Sun Oct 5 00:30:27 2014 -0400 + + Card view: don't escape
's in note field + +M NEWS +M UI/Contacts/UIxContactView.m + +commit 4cc6b72cfb434b79d8e0e5f2277fbc3a7f54a2ad +Author: Jeroen Dekkers +Date: Sun Oct 5 15:47:00 2014 +0200 + + Make png files non-executable + +M UI/WebServerResources/error.png +M UI/WebServerResources/notice.png +M UI/WebServerResources/success.png +M UI/WebServerResources/warning.png + +commit d7f8427623288493e9d082f793ed75870134c7e5 +Author: Francis Lachapelle +Date: Fri Oct 3 13:13:42 2014 -0400 + + Improve XSL for documentation + +M Documentation/Makefile +D Documentation/docbook/xsl/sogo-fo-article.xsl +M Documentation/docbook/xsl/sogo-fo.xsl + +commit 7f49dcb2fa0507d98741c3eeaa276f772de49886 +Author: Ludovic Marcotte +Date: Thu Oct 2 13:10:54 2014 -0400 + + Avoid using SOGO_SYSLIBDIR when testing since it's undefined + +M Tests/Integration/GNUmakefile.preamble + +commit f29a47d44328904a150c3c8ffc2a03af63293fb8 +Author: Ludovic Marcotte +Date: Thu Oct 2 12:42:06 2014 -0400 + + Added rpath + +M ActiveSync/common.make + +commit f88cfae611cda5462d5920638c1ff41856eb0a50 +Author: Ludovic Marcotte +Date: Thu Oct 2 12:36:22 2014 -0400 + + Improved and simplified rpath + +M SoObjects/common.make +M Tests/Integration/GNUmakefile.preamble + +commit fb3ddca9e8e3a5f8c5d4698dcb8046202f5ecc2d +Author: Ludovic Marcotte +Date: Thu Oct 2 11:17:45 2014 -0400 + + Improved makefiles + +M SoObjects/Mailer/GNUmakefile +M SoObjects/common.make + +commit ba4a50e778f586aaf5fc536b62b1ea00b9145292 +Author: Ludovic Marcotte +Date: Thu Oct 2 11:05:19 2014 -0400 + + Added rpath kungfu + +M SoObjects/common.make + +commit 8875c42d256444ed230bd834f7ed72fb1595cda2 +Author: Ludovic Marcotte +Date: Thu Oct 2 11:00:43 2014 -0400 + + Fixed makefile + +M SoObjects/common.make + +commit 18431922abd08be9a024589d16ee4117dcf9c477 +Author: Ludovic Marcotte +Date: Thu Oct 2 10:55:05 2014 -0400 + + Fixed makefile + +M ActiveSync/common.make + +commit f93c06e6a915889cc0d1a5de3b3d760efd5a100a +Author: Ludovic Marcotte +Date: Thu Oct 2 10:50:34 2014 -0400 + + Fixed include + +M Tests/Integration/GNUmakefile + +commit 68d79472a529b783273bf766bf4d5e5eb029343d +Author: Ludovic Marcotte +Date: Thu Oct 2 10:46:47 2014 -0400 + + Fixed makefile for teststrings due to sogo lib change + +M Tests/Integration/GNUmakefile +M Tests/Integration/GNUmakefile.preamble + +commit 51ed3717962c2d49f9c0824ced0efa700919dbff +Author: Ludovic Marcotte +Date: Thu Oct 2 10:21:36 2014 -0400 + + Adjusted debian install files regarding sogo lib move + +M packaging/debian-multiarch/sogo-dev.install +M packaging/debian-multiarch/sogo.install +M packaging/debian/sogo-dev.install +M packaging/debian/sogo.install + +commit 6ded9e95b33a80c09b00a63f7199b72f882d99d5 +Author: Jeroen Dekkers +Date: Wed Oct 1 20:36:42 2014 +0200 + + Put private libraries in /usr/lib/sogo + +M Main/GNUmakefile +M Main/GNUmakefile.preamble +M OpenChange/GNUmakefile +M SOPE/GDLContentStore/GNUmakefile +M SOPE/NGCards/GNUmakefile +M SoObjects/SOGo/GNUmakefile +M SoObjects/common.make +M Tests/Integration/GNUmakefile.preamble +M Tests/Unit/GNUmakefile +M Tools/GNUmakefile +M Tools/GNUmakefile.preamble +M UI/AdministrationUI/GNUmakefile +M UI/Common/GNUmakefile +M UI/Contacts/GNUmakefile +M UI/MailPartViewers/GNUmakefile +M UI/MailerUI/GNUmakefile +M UI/MainUI/GNUmakefile +M UI/PreferencesUI/GNUmakefile +M UI/SOGoUI/GNUmakefile +M UI/Scheduler/GNUmakefile +M UI/common.make + +commit 25b7fffb009333e07de5f0327288086de08cd942 +Author: Ludovic Marcotte +Date: Wed Oct 1 14:08:29 2014 -0400 + + Fix for bug #2930 + +M NEWS +M UI/MainUI/SOGoUserHomePage.m + +commit 89284d558c558c5bd2ec8c346fe5c16acbc1c366 +Author: Francis Lachapelle +Date: Wed Oct 1 09:02:03 2014 -0400 + + Add missing translation + +M UI/PreferencesUI/English.lproj/Localizable.strings + +commit 9610fcc5ca4faa9083e4be1c4cdf0bde53e7e228 +Author: Ludovic Marcotte +Date: Mon Sep 29 15:30:02 2014 -0400 + + Bumped version + +M Version + +commit 9cdcfd1d4a86de691a15b2a8d412c073f86dd145 +Author: Ludovic Marcotte +Date: Mon Sep 29 15:20:22 2014 -0400 + + Updated for the 2.2.9a release + +M NEWS +M Version + +commit 95b122c9125a3e8185a6b5fe0f1a7bd0bfefc130 +Author: Ludovic Marcotte +Date: Mon Sep 29 15:04:40 2014 -0400 + + Simplified even more -safeString + +M SoObjects/SOGo/NSString+Utilities.m + +commit aa0499dbacbefac0a7c2c8504eb94be22af26629 +Author: Ludovic Marcotte +Date: Mon Sep 29 14:28:13 2014 -0400 + + Fixed sanitization char skipping and #2936 + +M SoObjects/SOGo/NSString+Utilities.m +M UI/MailerUI/UIxMailListActions.m + +commit 80acafadd38b95dbd4917c157ea24d2a3467dd0c +Author: Francis Lachapelle +Date: Fri Sep 26 14:49:36 2014 -0400 + + Fix URL in documentation + +M Documentation/SOGoMozillaThunderbirdConfigurationGuide.asciidoc + +commit 4c5be2fd97ed230478ec330bc849cd3d96c31589 +Author: Ludovic Marcotte +Date: Fri Sep 26 14:31:57 2014 -0400 + + Update ChangeLog + +M ChangeLog + commit c0e8eb6ce3b2501a0439a95d6d4bfcb9b6c17cf0 Author: Ludovic Marcotte Date: Fri Sep 26 14:29:20 2014 -0400 @@ -1246,6 +3734,15 @@ Date: Fri Aug 1 12:26:53 2014 -0400 M UI/WebServerResources/SchedulerUI.js +commit 1a2fe8908b2f6feb674d69f47f034b253c2a444d +Author: Jesús García Sáez +Date: Wed Mar 19 17:19:07 2014 +0100 + + Revert "Merge pull request #2 from Zentyal/jgarcia/fix-encoding-of-mapistoreuris" + +M OpenChange/MAPIStoreContext.m +M OpenChange/MAPIStoreMailContext.m + commit cde1db93245c8bdfbf8e69ed8efe8a0f6a03027c Author: Ludovic Marcotte Date: Fri Aug 1 09:40:45 2014 -0400 @@ -1475,6 +3972,66 @@ M NEWS M UI/WebServerResources/SchedulerUI.css M UI/WebServerResources/SchedulerUI.js +commit f76a6cfc96aeefd1d5b913a29e60dcce6dfa9b5c +Author: Carlos Pérez-Aradros Herce +Date: Wed Jul 9 13:28:42 2014 +0200 + + Fix mysql cleanup log message + +M Scripts/openchange_user_cleanup + +commit 2b3bc10f786ce6948dfeb90d1752d975de5bbf51 +Author: Kamen Mazdrashki +Date: Thu Jul 3 14:59:49 2014 +0200 + + Scripts/openchange_user_cleanup: Don't hardcode samba private dir, use samba LoadParm() + + Signed-off-by: Kamen Mazdrashki + +M Scripts/openchange_user_cleanup + +commit 3eba5f940e353909628ab6fa59c4f402cccd0e32 +Author: Jesús García Sáez +Date: Wed Jul 2 12:24:09 2014 +0200 + + increase log level of debug message + +M OpenChange/MAPIStoreSOGo.m + +commit 7f2ee7be89d6dbbd0a70eb43a3ef32d6c56761c2 +Author: Jesús García Sáez +Date: Wed Jul 2 10:40:05 2014 +0200 + + Error message only when initialization hadn't been done + + In a multithread environment, sogo_backend_init is registering the thread + only for the first one that calls this function, then the others threads + (even if they call sogo_backend_init) won't be registered because + moduleInitialized was YES. + + We just want to ensure sogo_backend_init is called at least once (per process, + not per thread). + +M OpenChange/MAPIStoreSOGo.m + +commit 41f2e917e76e07f1f6a62dc7eea0e8aada9d2bce +Author: Miguel Julián +Date: Thu Jun 12 16:20:41 2014 +0200 + + Removed development tip comment + +M OpenChange/MAPIStoreAppointmentWrapper.m + +commit 65ece612734ec4fd88d08daeed5c86bd06fbd598 +Author: Miguel Julián +Date: Thu Jun 12 15:46:02 2014 +0200 + + Removing some trail characters at event description + + * They are sometimes present after a \r\n\n + +M OpenChange/MAPIStoreAppointmentWrapper.m + commit 94f3246658c151b55ca86404c607fe29de7b94b1 Author: Ludovic Marcotte Date: Tue Jul 29 10:36:20 2014 -0400 @@ -2025,6 +4582,409 @@ Date: Wed Jul 2 10:11:13 2014 -0400 M NEWS +commit 1846e1ee5db7120d4ebca9842ab402333b26cac5 +Author: Kamen Mazdrashki +Date: Tue Jun 24 15:28:42 2014 +0200 + + oc/TallocWrapper: don't handle Threading initialization here + + It is SOGo backend module responsibility to setup/teardonw all + ObjC specific initialization + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/NSObject+MAPIStore.m + +commit 1fc3a57210b61cc73a91757f5d7ddc4050dc5f7f +Author: Kamen Mazdrashki +Date: Thu Jun 19 20:41:37 2014 +0200 + + oc: Protect backend initialization to happen only once + +M OpenChange/MAPIStoreSOGo.m + +commit 5b75c817e21bb43c8a731ff2cb9a04f2e58bf080 +Author: Kamen Mazdrashki +Date: Thu Jun 19 19:57:32 2014 +0200 + + oc: Log when mapistore backend is successfully initialized + +M OpenChange/MAPIStoreSOGo.m + +commit c91741ad1f925b3acc828d88d28b82f640eb6997 +Author: Kamen Mazdrashki +Date: Thu Jun 19 19:43:14 2014 +0200 + + oc/dbmsgreader: Fix to work again this time basen on BSON format for msg data + + Also, implement reading for message data in case only 1 param is passed. + This could be usefull when have msg data by other means than by + reading it directly from DB + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/GNUmakefile +M OpenChange/dbmsgreader.m + +commit 86e54989fbba8997eb41eb0b1b84fd2f10faa0b7 +Author: Kamen Mazdrashki +Date: Fri Jun 20 03:23:38 2014 +0200 + + oc/utils: Make "plext" category publicly visible + + Signed-off-by: Kamen Mazdrashki + +A OpenChange/NSObject+PropertyList.h +M OpenChange/NSObject+PropertyList.m + +commit 116e738e63e7b281191b76665ce616961ca93293 +Author: Kamen Mazdrashki +Date: Thu Jun 19 19:30:17 2014 +0200 + + oc/utils: Move OCDumpPListData() function into plreader - this is the only user for this function + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/NSObject+PropertyList.m +M OpenChange/plreader.m + +commit bf0f2a76d565fc1f0265ad6f45e28c37c965dba3 +Author: Kamen Mazdrashki +Date: Mon Jun 16 13:20:51 2014 +0200 + + oc/MAPIStoreSOGo: Do not destroy current thread context after any API call + + We have thread context already in place during *_init() function. + Thus guarding every API call with TreadInit/Destroy is: + - a bit redundand + - makes SOGo backend not reentrant even on single thread and leads + to hard to find use-after-free crashes + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit 6de298d20285730e06fb41488ee6d97edfffbfab +Author: Kamen Mazdrashki +Date: Fri Jun 13 14:20:00 2014 +0200 + + oc/MAPIStoreMapping: Split the check for existing entry so we have better error message + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreMapping.m + +commit 98505c1b6b54c477e5c438d7fee3eac9ee100d66 +Author: Kamen Mazdrashki +Date: Fri Jun 13 14:19:20 2014 +0200 + + oc/MAPIStoreContext: Fix log messages to actually print 64bit FMIDs + + Signed-off-by: Kamen Mazdrashki + + Conflicts: + OpenChange/MAPIStoreContext.m + +M OpenChange/MAPIStoreContext.m + +commit 51df0adb79095dde2b0fc48f619a4b8497768970 +Author: Miguel Julián +Date: Thu Jun 12 16:20:41 2014 +0200 + + Removed development tip comment + +M OpenChange/MAPIStoreAppointmentWrapper.m + +commit 5d43513dd9f36dd47610c822bee3ace20e91aae5 +Author: Miguel Julián +Date: Thu Jun 12 15:46:02 2014 +0200 + + Removing some trail characters at event description + + * They are sometimes present after a \r\n\n + +M OpenChange/MAPIStoreAppointmentWrapper.m + +commit 2458af1a43e6e422538e3627313c591c7121b1d8 +Author: Miguel Julián +Date: Wed Jun 11 16:14:11 2014 +0200 + + All day events deladyed one day if user timezone is +XX:XX + + * Those events were not shown properly in SOGo web UI + +M OpenChange/iCalEvent+MAPIStore.m + +commit 2792baac028ecca9253e5ec88021e0cc7a8c7e53 +Author: Kamen Mazdrashki +Date: Mon Jun 2 01:20:18 2014 +0200 + + openchange: don't overflow possible recipient type while creating message headers + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreMailVolatileMessage.m + +commit 4b383705fff833a1c41dde513119fe847bbaefc7 +Author: Kamen Mazdrashki +Date: Mon Jun 2 01:18:23 2014 +0200 + + openchange: Fix submitWithFlags to submit to BCC-ed recipients also + + this reintroduces commit 7efb263c659451d2c781547a5b38cb5d01ed837f + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreMailVolatileMessage.m + +commit dd7200e00f6d975e8b4d3705745b49fae6509256 +Author: Kamen Mazdrashki +Date: Wed May 7 01:26:34 2014 +0200 + + openchange/MAPIStoreFolder: Add private selector for actual folder delete action + + Usually, it is a bad idea for an object to call its own public methods + (just like in this case). Thus separating impelementation for deleteFolder: + would allow MAPIStoreFolder to call only private implementation when needed + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreFolder.m + +commit 27851ef4280812ce5bf53c1cce33318a4774cc6f +Author: Kamen Mazdrashki +Date: Mon May 5 01:51:18 2014 +0200 + + openchange: FillMessageHeadersFromProperties fix skipping of last value in + possible range of recepients + + IMHO, this fixes a bug, that when saving a meessage, it is saved + without BCC fields. + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreMailVolatileMessage.m + +commit 7da8885190acac061bb54518cf6bbe305eb8d35b +Author: Kamen Mazdrashki +Date: Mon May 5 01:47:17 2014 +0200 + + openchange: getMessageData - replace int literals with ulRecipClass values + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreMailVolatileMessage.m + +commit fc9dc080455025f16c2ef58d14d8b16913eeb999 +Author: Kamen Mazdrashki +Date: Thu Mar 20 17:26:44 2014 +0100 + + oc-sogo: pretty print Exceptions in sogo_backend_handle_objc_exception() + + Now we have a nice stack trace printed out from [NSException callStackSymbols] + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit bcfb674cd1ba63189eb8210a95b388c0dc2468a6 +Author: Kamen Mazdrashki +Date: Thu Mar 20 17:04:11 2014 +0100 + + oc-sogo: Print both [NSException callStackSymbols] and execinfo.h stack trace + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit 6be768af42c7e21653149b81cfc1b2f09847d0f9 +Author: Kamen Mazdrashki +Date: Thu Mar 20 16:27:03 2014 +0100 + + oc-sogo: Move memory clean up *after* handling the exception + + Otherwise the mess is full :) + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit 2c94d21f3e62222304cd75ba7300acf1de8663fe +Author: Kamen Mazdrashki +Date: Thu Mar 20 15:52:21 2014 +0100 + + oc-sogo: Use [e name] and [e reason] selectors + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit cbe616358dde8a1bbc19d5c84e0371402a919532 +Author: Kamen Mazdrashki +Date: Thu Mar 20 14:36:29 2014 +0100 + + oc-sogo: Clean up AutoRelease pool and unregister threads in Catch handler + + Most of the time we have "not yet implemented" kind of exceptions, + so it is better to clean up allocated resources + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit 09e6fcc3ff2021b1a9a4a2d99e8a4a852f8c5c93 +Author: Kamen Mazdrashki +Date: Thu Mar 20 14:24:58 2014 +0100 + + oc-sogo: try/catch to guard only the actual impelementation rather than *everything* + + Signed-off-by: Kamen Mazdrashki + +M OpenChange/MAPIStoreSOGo.m + +commit 3b2174eeec1843eeb011129134cecf5b6bfd2246 +Author: Jesús García Sáez +Date: Mon Mar 17 21:08:12 2014 +0100 + + if there is no password file for specific user, try to read global password file + + This way we can have a master password for imap access + +M OpenChange/MAPIStoreUserContext.m + +commit c6b8be742d1197ad24f0d1735db36892a6b4c1aa +Author: Jesús García Sáez +Date: Tue Mar 4 16:40:41 2014 +0100 + + use execinfo.h to get backtrace + + Really poor backtrace because it will only have the frames from oc side, + I don't know why callStackSymbols is returning null, compilation flags? + +M OpenChange/MAPIStoreSOGo.m + +commit a77863947f92730dbd407f25c0e65fc0a9b51c55 +Author: Jesús García Sáez +Date: Tue Mar 4 12:29:13 2014 +0100 + + add try catch to all functions on struct mapistore_backend + +M OpenChange/MAPIStoreSOGo.m + +commit d1f54298d29963e76f12e3cc2ef4abf07b697f68 +Author: Jesús García Sáez +Date: Mon Mar 3 16:09:30 2014 +0100 + + stringByDecodingImap4FolderName is not neccesary + + For russian locale and characters nonexistent in latin1 sogo crashes + +M OpenChange/MAPIStoreMailContext.m + +commit f8028b5a94f1899ca1f20fa3f63d8949c91c7069 +Author: Kamen Mazdrashki +Date: Sat Feb 22 23:01:41 2014 +0100 + + OpenChange: Avoid crashing when creating embedded message in attachment + + Signed-off-by: Kamen Mazdrashki + (cherry picked from commit 15a55f9f707247c9164e8fa7a102639744f686e5) + +M OpenChange/MAPIStoreSOGo.m + +commit 6bef67811432f5685802cb134d85cffd79de2e41 +Author: Jesús García Sáez +Date: Thu Feb 27 17:47:28 2014 +0100 + + fix format logging uint64_t + +M OpenChange/MAPIStoreContext.m + +commit c81476bd040508bf2e70e51ef8052c5400746777 +Author: Jesús García Sáez +Date: Thu Feb 27 17:46:55 2014 +0100 + + no need to modify url + +M OpenChange/MAPIStoreContext.m + +commit a24f009cfe88be15977c661b7fcc100dd76a6f6b +Author: Jesús García Sáez +Date: Thu Feb 27 17:42:58 2014 +0100 + + mapistoreURI encoding should be done the same way as listContextForUser + + stringByEncodingImap4FolderName is used inside [newFolder create] where is needed + +M OpenChange/MAPIStoreMailContext.m + +commit 95298de9f18ce440355eb6ef783e7294d9432a22 +Author: Jesús García Sáez +Date: Mon Feb 10 12:38:42 2014 +0100 + + avoid infinite loop when trying to update a folder id + +M OpenChange/MAPIStoreMapping.m + +commit f6d1a37127eea974a3a64c1cea138b796d62eaa2 +Author: Jesús García Sáez +Date: Tue Dec 24 11:03:03 2013 +0100 + + use properly get_uri function and check ret value + +M OpenChange/MAPIStoreMapping.m + +commit 2aa71cc8a3fdc94b925773ce5dc5cd3b0eced242 +Author: Jesús García Sáez +Date: Fri Dec 20 11:26:09 2013 +0100 + + check ret value properly + +M OpenChange/MAPIStoreContext.m + +commit 34b98a563dec2229a6d7c363e1f77a659d872bb7 +Author: Jesús García Sáez +Date: Tue Nov 19 15:24:31 2013 +0100 + + get_new_folderID functions are now on mapistore_indexing + +M OpenChange/MAPIStoreContext.m + +commit fd308b592fcf8c7052258c4e2e17d25278344e26 +Author: Carlos Pérez-Aradros Herce +Date: Mon Nov 11 03:17:53 2013 +0100 + + Converted all the indexing code to indexing backends + +M OpenChange/MAPIStoreMapping.m + +commit a6bfb9d5c50b2fa299b6bb583dd33630848c0d6f +Author: Carlos Pérez-Aradros Herce +Date: Sat Nov 9 18:00:44 2013 +0100 + + Use indexing generic code instead of tdb private funtions + +M OpenChange/MAPIStoreMapping.h +M OpenChange/MAPIStoreMapping.m + +commit 33b353b97442c106dba2b63b29954f05af9c34b6 +Author: Carlos Pérez-Aradros Herce +Date: Fri Nov 8 17:02:50 2013 +0100 + + Moved to abstract index_context instead of tdb_wrap + +M OpenChange/MAPIStoreContext.h +M OpenChange/MAPIStoreContext.m +M OpenChange/MAPIStoreFallbackContext.m +M OpenChange/MAPIStoreGCSBaseContext.m +M OpenChange/MAPIStoreMailContext.m +M OpenChange/MAPIStoreMapping.h +M OpenChange/MAPIStoreMapping.m +M OpenChange/MAPIStoreNotesContext.m +M OpenChange/MAPIStoreSOGo.m +M OpenChange/MAPIStoreUserContext.h +M OpenChange/MAPIStoreUserContext.m + commit 899a1eb026503165436a333110fa6eb73522c5a6 Author: Ludovic Marcotte Date: Wed Jul 2 08:39:01 2014 -0400 diff --git a/Documentation/Makefile b/Documentation/Makefile index 40bc10436..ee7246fba 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,7 +1,7 @@ all: $(patsubst %.asciidoc,%.pdf,$(wildcard *.asciidoc)) %.pdf : %.asciidoc - asciidoc -a docinfo1 -b docbook -d book -d book -o $<.docbook $< + asciidoc -a docinfo1 -b docbook -d book -o $<.docbook $< fop -c fonts/fop-config.xml -xsl docbook/xsl/sogo-fo.xsl -xml $<.docbook -pdf $@ clean: diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index c4f077505..e88affe42 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -80,6 +80,12 @@ and others)  * SMTP server (Postfix, Sendmail and others) * IMAP server (Courier, Cyrus IMAP Server, Dovecot and others) +If you plan to use ActiveSync, an IMAP server supporting the ACL, +UIDPLUS, QRESYNC, ANNOTATE (or X-GUID) IMAP extensions is required, +such as Cyrus IMAP version 2.4 or later, or Dovecot version +2.1 or later. If your current IMAP server does not support these +extensions, you can use Dovecot's proxying capabilities. + In this guide, we assume that all those components are running on the same server (i.e., `localhost` or `127.0.0.1`) that SOGo will be installed on. @@ -193,7 +199,7 @@ installation for a Red Hat or CentOS distribution. Software Downloads ~~~~~~~~~~~~~~~~~~ -SOGo can be installed using the+yum+utility. To do so, first create +SOGo can be installed using the `yum` utility. To do so, first create the `/etc/yum.repos.d/inverse.repo` configuration file with the following content: @@ -258,13 +264,13 @@ In SOGo, the user's applications settings are stored in `/etc/sogo/sogo.conf`. You can use your favourite text editor to modify the file. -The +sogo.conf+ file is a serialized _property list_. This simple format +The `sogo.conf` file is a serialized _property list_. This simple format encapsulates four basic data types: arrays, dictionaries (or hashes), strings and numbers. Numbers are represented as-is, except for booleans which can take the unquoted values `YES` and `NO`. Strings are not mandatorily quoted, but doing so will avoid you many problems. A dictionary is a sequence of key and value pairs separated in their -middle with a `=` sign. It starts with a `\{` and ends with a +middle with a `=` sign. It starts with a `{` and ends with a corresponding `}`. Each value definition in a dictionary ends with a semicolon. An array is a chain of values starting with `(` and ending with `)`, where the values are separated with a `,`. Also, the file @@ -273,6 +279,11 @@ is not required, only recommended. Block comments are delimited by `/*` and `*/` and can span multiple lines while line comments must start with `//`. +The configuration must be contained in a root dictionary, thus be completely +wrapped within curly brackets `{ [configuration] }`. If SOGo refuses to +start due to syntax errors in its configuration file, `plparse` is helpful +for finding these, as it indicates the line containing the problem. + Preferences Hierarchy ~~~~~~~~~~~~~~~~~~~~~ @@ -425,29 +436,42 @@ Defaults to `YES` when unset. |The location of the SSL private key file on the filesystem that is used by SOGo to sign and encrypt communications with the SAML2 identity provider. This file must be generated for each running SOGo service -(rather than host). +(rather than host). Make sure this file is readable by the SOGo user. |S |SOGoSAML2CertiticateLocation |The location of the SSL certificate file. This file must be generated -for each running SOGo service. +for each running SOGo service. Make sure this file is readable by the SOGo user. |S |SOGoSAML2IdpMetadataLocation |The location of the metadata file that describes the services available -on the SAML2 identify provider. +on the SAML2 identify provider. The content of this file is usually generated +directly by your SAML 2.0 IdP solution. For example, using SimpleSAMLphp, you +can get the metadata directly from https://MYSERVER/simplesaml/saml2/idp/metadata.php +Make sure this file is readable by the SOGo user. |S |SOGoSAML2IdpPublicKeyLocation |The location of the SSL public key file on the filesystem that is used by SOGo to sign and encrypt communications with the SAML2 identity provider. This file should be part of the setup of your identity -provider. +provider. Make sure this file is readable by the SOGo user. |S |SOGoSAML2IdpCertificateLocation |The location of the SSL certificate file. This file should be part of -the setup of your identity provider. +the setup of your identity provider. Make sure this file is readable by the SOGo user. + +|S |SOGoSAML2LoginAttribute +|The attribute provided by the IdP to identify the user in SOGo. |S |SOGoSAML2LogoutEnabled |Boolean value indicated whether the "Logout" link is enabled when using -SAML2 as authentication mechanism. +SAML2 as authentication mechanism. When using this feature, SOGo will invoke +the IdP to proceed with the logout procedure. When the user clicks on the logout +button, a redirection will be made to the IdP to trigger the logout. + +|S |SOGoSAML2LogoutURL +|The URL to which redirect the user after the "Logout" link is clicked. +SOGoSAML2LogoutEnabled must be set to YES. If unset, the user will be +redirected to a blank page. |D |SOGoTimeZone |Parameter used to set a default time zone for users. The default @@ -887,7 +911,8 @@ resource if the entry has the calendarresource objectClass set. to which a resource can be part of at any point in time. If this is set to `0`, or if the attribute is missing, it means no -limit. +limit. If set to `-1`, no limit is imposed but the resource will +be marked as busy the first time it is booked. |filter (optional) |The filter to use for LDAP queries, it should be defined as an @@ -974,7 +999,9 @@ context as Dovecot stores in its database. |passwordPolicy |If set to `YES`, SOGo will use the extended LDAP Password Policies attributes. If you LDAP server does not support those and you activate -this feature, every LDAP requests will fail. +this feature, every LDAP requests will fail. Note that some LDAP servers +require LDAP/SSL for password policies to work. This is the case for +example with 389 Directory Server. |isAddressBook |If set to `YES`, this LDAP source is used as a shared address book @@ -1167,7 +1194,7 @@ keytool -import -keystore /etc/ssl/certs/java/cacerts \ *The certificate used by the CAS server must also be trusted by SOGo.* In case of a self-signed certificate, this means exporting tomcat's -certificate using the +keytool+utility, converting it to PEM format and +certificate using the `keytool` utility, converting it to PEM format and appending it to the `ca-certificates.crt` file (the name and location of that file differs between distributions). Basically: @@ -1230,13 +1257,32 @@ documentation of your identity provider and the SAML2 configuration keys that are listed above for proper setup. Once a SOGo instance is configured properly, the metadata for that instance can be retrieved from `http:///SOGo/saml2-metadata` for registration with the -identity provider. +identity provider. SOGo will dynamically generate the metadata based on +the SOGoSAML2CertificateLocation's content and the SOGo server name. + +When using SimpleSAMLphp, make sure the convert OID to names by modifying your +`metadata/saml20-idp-hosted.php` to contain something like this: + +---- + 'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', + 'authproc' => array( + 100 => array('class' => 'core:AttributeMap', 'oid2name'), + ), +---- + +If you want to test the IdP-initiated logout using SimpleSAMLphp, you can do so by opening +the following URL: + +---- +https://idp.example.org/simplesaml/saml2/idp/SingleLogoutService.php?ReturnTo=www.sogo.nu +---- In order to relay authentication information to your IMAP server and if you make use of the CrudeSAML SASL plugin, you need to make sure that _NGImap4AuthMechanism_ is configured to use the `SAML` mechanism. If you make use of the CrudeSAML PAM plugin, this value may be left empty. + Database Configuration ~~~~~~~~~~~~~~~~~~~~~~ @@ -1433,7 +1479,10 @@ case, SOGo will consider the returned entry to be a resource. which a resource can be part of at any point in time. If this is set to `0`, or if the attribute is missing, it means no -limit. +limit and the resource will always be marked as free. If set to `-1`, +no limit is imposed but the resource will be marked as busy the first +time it is booked. If greater than 0, the resource will get marked as +busy once it reaches the value. |DomainFieldName (optional) |If set, SOGo will use the value of that field as the domain associated @@ -1581,8 +1630,8 @@ Note that TLS is supported but SSL is not. |D |SOGoSieveFolderEncoding |Parameter used to specify which encoding is used for IMAP folder names -in Sieve filters. Defaults to "UTF-7". The other possible value is -"UTF-8". +in Sieve filters. Defaults to `UTF-7`. The other possible value is +`UTF-8`. |U |SOGoMailShowSubscribedFoldersOnly |Parameter used to specify if the Web interface should only show @@ -1632,6 +1681,12 @@ cronjob `sogo-tmpwatch`. Defaults to `/var/spool/sogo`. +|S |NGImap4DisableIMAP4Pooling +|Disables IMAP pooling when set to `YES`. Enable pooling by setting to +`NO` or using a caching proxy like imapproxy. + +The default value is `YES`. + |S |NGImap4ConnectionStringSeparator |Parameter used to set the IMAP mailbox separator. Setting this will also have an impact on the mailbox separator used by Sieve filters. @@ -1644,7 +1699,7 @@ SASL mechanism. Please note that feature might be limited at this time. |D |NGImap4ConnectionGroupIdPrefix |Prefix to prepend to names in IMAP ACL transactions, to indicate the -name is a group name not a user name. +name is a group name, not a user name. RFC4314 gives examples where group names are prefixed with `$`. Dovecot, for one, follows this scheme, and will, for example, apply permissions @@ -1993,7 +2048,7 @@ Defaults to `NO` when unset. SOGo Configuration Summary ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The complete SOGo configuration file+/etc/sogo/sogo.conf+should look +The complete SOGo configuration file `/etc/sogo/sogo.conf` should look like this: ---- @@ -2325,7 +2380,7 @@ ActiveSync: |Parameter used to set the maximum amount of time, in seconds, SOGo will wait before replying to a Ping command. -If not set, it defaults to `5` seconds. +If not set, it defaults to `10` seconds. |S |SOGoMaximumSyncInterval |Parameter used to set the maximum amount of time, in seconds, SOGo will @@ -2336,10 +2391,20 @@ If not set, it defaults to `30` seconds. |S |SOGoInternalSyncInterval |Parameter used to set the maximum amount of time, in seconds, SOGo will wait before doing an internal check for data changes (add, delete, and -update). This parameter must be lower than _SOGoMaximumSyncInterval_. +update). This parameter must be lower than _SOGoMaximumSyncInterval_ and +_SOGoMaximumPingInterval_. If not set, it defaults to `10` seconds. +|S |SOGoMaximumSyncResponseSize +|Parameter used to overwrite the maximum response size during +a Sync operation. The value is in kilobytes. Setting this to 512 +means the response size will be of 524288 bytes or less. Note that +if you set the value too low and a mail message (or any other object) +surpasses it, it will still be synced but only this item will be. + +Defaults to `0`, which means no overwrite is performed. + |S |SOGoMaximumSyncWindowSize |Parameter used to overwrite the maximum number of items returned during a Sync operation. @@ -2352,24 +2417,18 @@ have unexpected behaviour with various ActiveSync clients. Please be aware of the following limitations: -* Currently, only the personal calendar and address book are -synchronized. Adding support for all folders is planned. -* When creating an Outlook 2013 profile, you must actually kill Outlook -before the end of the creation process. See http://www.vionblog.com/connect-zimbra-community-with-outlook-2013 -for a procedure example. * Outlook 2013 does not search the GAL. One possible alternative solution is to configure Outlook to use a LDAP server (over SSL) with -authentication. Alternatively, when supporting more than just the -personal address book, we'll also be able to expose the LDAP/SQL based -address books in SOGo over ActiveSync. +authentication. Outlook 2013 also does not seem to support multiple +address books over ActiveSync. * Make sure you do not use a self-signed certificate. While this will work, Outlook will work intermittently as it will raise popups for certificate validation, sometimes in background, preventing the user to see the warning and thus, preventing any synchronization to happen. * ActiveSync clients keep connections open for a while. Each connection will grab a hold on a sogod process so you will need a lot of processes -to handle many clients. This limitation will eventually be overcome in -SOGo. +to handle many clients. Make sure you tune your SOGo server when having +lots of ActiveSync clients. * Repetitive events with occurrences exceptions are currently not supported. * Outlook 2013 Autodiscovery is currently not supported. @@ -2379,6 +2438,10 @@ see http://support.microsoft.com/kb/291621 for configuration instructions. On the SOGo side, _SOGoEnablePublicAccess_ must be set to `YES` and the URL to use must be of the following format: `http:///SOGo/dav/public/%NAME%/freebusy.ifb` +* If you have very large mail folders (thousands of messages), you will +need to adjust the word size of your IMAP server. In Dovecot, the parameter +to increase is "imap_max_line_length" while under Cyrus IMAP Server, the +parameter is "maxword". We suggest a buffer of 2MB. In order to use the SOGo ActiveSync support code in production environments, you need to get a proper usage license from Microsoft. @@ -2387,7 +2450,7 @@ user base. To contact Microsoft, please visit: -http://www.microsoft.com/en-us/legal/intellectualproperty/IPLicensing/Programs/exchangeactivesyncprotocol.aspx +http://www.microsoft.com/en-us/legal/intellectualproperty/   and send an email to iplicreq@microsoft.com @@ -2513,7 +2576,7 @@ any mobile devices that support Microsoft ActiveSync. Microsoft Outlook 2013 is also supported. The Microsoft ActiveSync server URL is generally something -like: `http://localhost/Microsoft-Active-Sync`. +like: `http://localhost/Microsoft-Server-ActiveSync`. Upgrading --------- diff --git a/Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc b/Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc index 75eb4eb86..99efb47fe 100644 --- a/Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc +++ b/Documentation/SOGoNativeOutlookConfigurationGuide.asciidoc @@ -233,13 +233,12 @@ Installation This section will guide you through the installation of the native Microsoft Outlook compatibility layer SOGo offers. -Red Hat Enterprise Linux v5 and v6 +Red Hat Enterprise Linux v6 x86_64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you are using Red Hat Enterprise Linux (or CentOS) version 5 or -version 6, packages for Samba 4, OpenChange and SOGo and the SOGo -OpenChange backend are available from SOGo's web site. Please follow the -instructions from +If you are using Red Hat Enterprise Linux version 6 x86_64, packages +for Samba 4, OpenChange and SOGo and the SOGo OpenChange backend are +available from SOGo's web site. Please follow the instructions from http://www.sogo.nu/english/downloads/backend_nightly.html. In order to satisfy certain dependencies, you should also add the EPEL @@ -253,53 +252,48 @@ installation: ---- yum clean all && yum makecache -yum install samba4 \ +yum install samba \ openchange \ sogo-openchange-backend \ openchange-ocsmanager \ - openchange-rpcproxy + openchange-rpcproxy \ + mysql-server \ + MySQL-python ---- Once the packages are installed, refer to the _Configuration_ chapter from this guide. -Debian 6.0 (Squeeze) and Ubuntu 12.04 (Precise Pangolin) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[NOTE] +Samba4/OpenChange are not available for now on CentOS 5 i386/x86_64, +CentOS 6 i386 and CentOS 7. -Samba 4, OpenChange, SOGo and the SOGo OpenChange backend are now +Debian 7.0 (Wheezy) and Ubuntu 12.04 (Precise Pangolin) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SOGo, OpenChange and the SOGo OpenChange backend are now available from SOGo's web site. Please follow the instructions from -http://www.sogo.nu/english/downloads/backend_nightly.html to setup your +http://www.sogo.nu/english/downloads/backend.html to setup your apt sources. -Debian Squeeze ships an older version of some libraries required by -Samba 4. In order to workaround this, users of this distribution will -have to use the _squeeze-backports_ repository. To do so, create +For Samba 4, you need to use the _wheezy-backports_ repository. To do so, create `/etc/apt/sources.list.d/backports.list`: - deb http://backports.debian.org/debian-backports squeeze-backports main + deb http://http.debian.net/debian wheezy-backports main -Then install the dependencies on Debian Squeeze, do: +On Ubuntu 12.04, you will also have to add the Wheezy sources: ----- -apt-get update -apt-get install -t squeeze-backports libwbclient-dev samba-common smbclient libsmbclient libsmbclient-dev ----- + deb http://ftp.us.debian.org/debian wheezy main + deb http://security.debian.org/ wheezy/updates main -Once ready, install the `samba4` package on top of an existing SOGo +Then install Samba 4 on top of an existing SOGo installation: ---- apt-get update -apt-get install samba4 +apt-get -t wheezy-backports install samba samba-dev ---- -The current post installation script shipped with the Samba 4 package is -far from perfect and might fail even on a fresh install. The following -command is needed to let dpkg know that everything is fine about Samba 4 -if the post install script fails. - - sed --in-place 'N; s/Package: samba4\nStatus: install ok half-configured/Package: samba4\nStatus: install ok installed/;' /var/lib/dpkg/status - Once completed, install the packages related to OpenChange and the SOGo provider: @@ -307,13 +301,53 @@ provider: apt-get install openchangeserver \ sogo-openchange \ openchangeproxy \ - openchange-ocsmanager \ - openchange-rpcproxy + python-ocsmanager \ + mysql-server \ + python-mysqldb ---- Once the packages are installed, refer to the _Configuration_ chapter from this guide. +[NOTE] +On Ubuntu 12.04, the Samba init scripts need to be modified to +disable the upstart check. For more details, refer to: +https://wiki.samba.org/index.php/Samba4/InitScript + + +Ubuntu 14.04 (Trusty Tahr) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For Ubuntu 14.04, you must not use the Debian Wheezy backports. + +Please follow the instructions from +http://www.sogo.nu/english/downloads/backend.html to setup your +apt sources. + +Then install Samba 4 on top of an existing SOGo +installation: + +---- +apt-get update +apt-get install samba samba-dev +---- + +Once completed, install the packages related to OpenChange and the SOGo +provider: + +---- +apt-get install openchangeserver \ + sogo-openchange \ + openchangeproxy \ + python-ocsmanager \ + mysql-server \ + python-mysqldb +---- + +Once the packages are installed, refer to the _Configuration_ chapter +from this guide. + + Configuration ------------- @@ -349,16 +383,14 @@ You might consider changing the realm and domain used, to suit your enviroment. You might also have to -remove `/etc/samba4/smb.conf` (or `/etc/samba/smb.conf` on Debian-based -distributions) prior running this command. +remove `/etc/samba/smb.conf` prior running this command. Add the following parameters to the `[global]` section of the -`/etc/samba4/smb.conf` (`/samba/smb.conf` if you use a Debian-based -distribution) configuration file: +`/etc/samba/smb.conf` configuration file: ---- ### Configuration required by OpenChange server ### -dcerpc endpoint servers = +epmapper, +mapiproxy +dcerpc endpoint servers = epmapper, mapiproxy, dnsserver dcerpc_mapiproxy:server = true dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr ### Configuration required by OpenChange server ### @@ -392,11 +424,22 @@ Your Samba 4 configuration file should look like this: OpenChange Configuration ~~~~~~~~~~~~~~~~~~~~~~~~ +OpenChange 2.2 stores its metadata in MySQL so you need to have it installed. + +First, create the OpenChange MySQL user: + +---- +$ mysql -u root -p +mysql> CREATE USER 'openchange-user'@'localhost' IDENTIFIED BY 'openchange$123'; +mysql> GRANT ALL PRIVILEGES ON `openchange`.* TO 'openchange-user'@'localhost' WITH GRANT OPTION; +mysql> FLUSH PRIVILEGES; +---- + The Samba AD schema needs to be filled with additional object definitions by running the following commands:  ---- -openchange_provision +openchange_provision --standalone NOTE: This operation can take several minutes [+] Step 1: Register Exchange OIDs @@ -410,38 +453,59 @@ NOTE: This operation can take several minutes [+] Step 9: Add Exchange classes to Samba schema [+] Step 10: Add possSuperior attributes to Exchange classes [+] Step 11: Extend existing Samba classes and attributes -[+] Step 12: Exchange Samba with Exchange configuration objects +[+] Step 12: Generic Exchange configuration objects +[+] Step 13: Finalize generic Exchange configuration objects +[SUCCESS] Done! +[+] Step 1: Exchange Samba registration +[SUCCESS] Done! +[+] Step 1: Register Exchange Samba as the main server [SUCCESS] Done! ---- -You can safely ignore the "`ERROR: no subClassOf 'serviceAdministrationPoint' for 'rRASAdministrationConnectionPoint'`" message when running the `openchange_provision` command. - -Provision the OpenChange database:  +Create the OpenChange database:  ---- -openchange_provision --openchangedb +openchange_provision --openchangedb --openchangedb-uri 'mysql://openchange-user:openchange$123@localhost/openchange' Setting up openchange db [+] Public Folders =================== - * Public Folder Root 0x0100000000000001 - * IPM_SUBTREE 0x0200000000000001 - * NON_IPM_SUBTREE 0x0300000000000001 - * EFORMS REGISTRY 0x0400000000000001 - * OFFLINE ADDRESS BOOK 0x0500000000000001 - * /o=First Organization/cn=addrlists/cn=oabs/cn=Default Offline Address Book 0x0600000000000001 - * SCHEDULE+ FREE BUSY 0x0700000000000001 - * EX:/o=First Organization/ou=Exchange Administrative Group (UBUNTU-OC) 0x0800000000000001 - * Events Root 0x0900000000000001 + * Public Folder Root : 0x0100000000000001 (72057594037927937) + * IPM_SUBTREE : 0x0200000000000001 (144115188075855873) + * NON_IPM_SUBTREE : 0x0300000000000001 (216172782113783809) + * EFORMS REGISTRY : 0x0400000000000001 (288230376151711745) + * OFFLINE ADDRESS BOOK : 0x0500000000000001 (360287970189639681) + * /o=First Organization/cn=addrlists/cn=oabs/cn=Default Offline Address Book: 0x0600000000000001 (432345564227567617) + * SCHEDULE+ FREE BUSY : 0x0700000000000001 (504403158265495553) + * EX:/o=first organization/ou=first administrative group: 0x0800000000000001 (576460752303423489) + * Events Root : 0x0900000000000001 (648518346341351425) +---- + +Finally, modify `/etc/samba/smb.conf` to specify OpenChange connection information +for its indexing database. Add the following at the end of the `[global]` section: + +---- +mapistore:namedproperties = mysql +namedproperties:mysql_user = openchange-user +namedproperties:mysql_pass = openchange$123 +namedproperties:mysql_host = localhost +namedproperties:mysql_db = openchange + +mapistore:indexing_backend = mysql://openchange-user:openchange$123@localhost/openchange +mapiproxy:openchangedb = mysql://openchange-user:openchange$123@localhost/openchange ---- On RHEL, make sure SELinux is disabled: setenforce 0 -Next, you can start Samba using the usual command : +Next, you can start Samba using the usual command: - /etc/init.d/samba4 start + /etc/init.d/samba start + +On upstart-based distributions, use: + + start samba-ad-dc You can also launch the OpenChange web services: @@ -503,6 +567,10 @@ On Debian-based distributions, do: update-rc.d apache2 defaults && /etc/init.d/apache2 restart +[NOTE] +Debian-based distributions are not supported anymore for +OCSManager/rpcproxy. Support will soon resume. + Name Service Configuration for Web Services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -540,14 +608,13 @@ samba-tool domain passwordsettings set --complexity=off samba-tool domain passwordsettings set --min-pwd-length=1 samba-tool user add samba-tool user setexpiry --noexpiry -# create user in openchange+ +openchange_newuser --create +# create user in openchange +openchange_newuser --create ---- If you don't have a trust between your IMAP server and SOGo, you must at this point set the cleartext password of the newly created user in -`/var/lib/samba4/private/mapistore/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Lato-Medium - - - 0.5em - solid 2px - 1em - - - solid 1px - 1em - 1em - - - 1em - 1em - - - 1em - - - 1em - - - - - 1.5em - 1.5em - 2.2em - - - - Lato-Light - 10 - Incosolata - - - - 12pt - bold - center - - - page - - - 1px solid - - - - - - - - - - - - - 0em - 0em - 0.2em - - - - - - - - - - - - - square - - - - - - images/ - .png - - 1px solid - 1px solid - 0.5em - 0.5em - 2em - - - - - - - #E0E0E0 - thin #9F9F9F solid - 0pt - 0.5em - - always - - - - - wrap - - - - - - - - blue - underline - - - - - - - - - - diff --git a/Documentation/docbook/xsl/sogo-fo.xsl b/Documentation/docbook/xsl/sogo-fo.xsl index 4f5c4ba31..5ab3c7396 100644 --- a/Documentation/docbook/xsl/sogo-fo.xsl +++ b/Documentation/docbook/xsl/sogo-fo.xsl @@ -165,6 +165,13 @@ underline + + + + + + + diff --git a/Documentation/docinfo.xml b/Documentation/docinfo.xml index ade228dca..00fc54948 100644 --- a/Documentation/docinfo.xml +++ b/Documentation/docinfo.xml @@ -1,7 +1,7 @@ -Version 2.2.9 - September 2014 -for version 2.2.9 -2014-09-26 +Version 2.2.15 - January 2015 +for version 2.2.15 +2015-01-30 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". diff --git a/Documentation/includes/global-attributes.asciidoc b/Documentation/includes/global-attributes.asciidoc index b5707df1b..0cbd771ae 100644 --- a/Documentation/includes/global-attributes.asciidoc +++ b/Documentation/includes/global-attributes.asciidoc @@ -6,13 +6,13 @@ Authors: - Inverse inc. - Copyright (C) 2008-2014 Inverse inc. + Copyright (C) 2008-2015 Inverse inc. License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html //// // TODO have the build system take care of this -:release_version: 2.2.9 +:release_version: 2.2.15 // vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab: diff --git a/Main/GNUmakefile b/Main/GNUmakefile index 962730cbc..ed6b61051 100644 --- a/Main/GNUmakefile +++ b/Main/GNUmakefile @@ -6,8 +6,7 @@ include ../Version ADDITIONAL_OBJCFLAGS += -fPIE ADDITIONAL_INCLUDE_DIRS += -ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj/ -ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -fPIE -pie +ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -fPIE -pie -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo SOGOD = sogod TOOL_NAME = $(SOGOD) diff --git a/Main/GNUmakefile.preamble b/Main/GNUmakefile.preamble index 022e3d1e2..bc6998db8 100644 --- a/Main/GNUmakefile.preamble +++ b/Main/GNUmakefile.preamble @@ -9,10 +9,9 @@ ADDITIONAL_INCLUDE_DIRS += \ -I.. ADDITIONAL_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework \ - -L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ - -SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib + -L../SoObjects/SOGo/SOGo.framework/sogo \ + -L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \ + -L../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/ $(SOGOD)_TOOL_LIBS += \ -lSOGo \ diff --git a/Main/SOGo.m b/Main/SOGo.m index 2eb4a9bd8..8e8959b2c 100644 --- a/Main/SOGo.m +++ b/Main/SOGo.m @@ -245,7 +245,7 @@ static BOOL debugLeaks; } else { - NSLog (@"No value specified for '%@'", *urlString); + [self errorWithFormat: @"No value specified for '%@'", *urlString]; ok = NO; } } @@ -283,7 +283,7 @@ static BOOL debugLeaks; { id authenticator; - if (trustProxyAuthentication) + if (trustProxyAuthentication && [[context request] headerForKey: @"x-webobjects-remote-user"]) authenticator = [SOGoProxyAuthenticator sharedSOGoProxyAuthenticator]; else { @@ -441,7 +441,7 @@ static BOOL debugLeaks; if (debugLeaks) { if (debugOn) - NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES)); + [self logWithFormat: @"allocated classes:\n%s", GSDebugAllocationList (YES)]; else { debugOn = YES; diff --git a/Main/sogod.m b/Main/sogod.m index 4a123b938..4d6a488ae 100644 --- a/Main/sogod.m +++ b/Main/sogod.m @@ -1,15 +1,15 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG - Copyright (C) 2006-2009 Inverse inc. + Copyright (C) 2006-2015 Inverse inc. - This file is part of OpenGroupware.org. + This file is part of SOGo. - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo 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 Lesser General Public License for more details. diff --git a/NEWS b/NEWS index e2d50e2a8..8177e4989 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,126 @@ +2.2.15 (2015-01-30) +------------------- + +Enhancements + - improved handling of EAS Push when no heartbeat is provided + - no longer need to kill Outlook 2013 when creating EAS profiles (#3076) + - improved server-side CSS cleaner (#3040) + - unified the logging messages in sogo.log file (#2534/#3063) + - updated Brazilian (Portuguese) and Hungarian translations + +2.2.14 (2015-01-20) +------------------- + +Enhancements + - MultipleBookingsFieldName can be set to -1 to show busy status when booked at least once + - handle multipart objects in EAS/ItemOperations + +Bug fixes + - fixed calendar selection in event and task editors (#3049, #3050) + - check for resources existence when listing subscribed ones (#3054) + - correctly recognize Apple Calendar on Yosemite (#2960) + - fixed two potential autorelease pool leaks (#3026 and #3051) + - fixed birthday offset in EAS + - fixed From's full name over EAS + - fixed potential issue when handling multiple Add/Change/Delete/Fetch EAS commands (#3057) + - fixed wrong timezone calculation on recurring events + +2.2.13 (2014-12-30) +------------------- + +Enhancements + - initial support for empty sync request/response for EAS + - added the SOGoMaximumSyncResponseSize EAS configuration parameter to + support memory-limited sync response sizes + - we now not only use the creation date for event's cutoff date (EAS) + +Bug fixes + - fixed contact description truncation on WP8 phones (#3028) + - fixed freebusy information not always returned + - fixed tz issue when the user one was different from the system one with EAS + +2.2.12a (2014-12-19) +-------------------- + +Bug fixes + - fixed empty HTML mails being sent (#3034) + +2.2.12 (2014-12-18) +------------------- + +New features + - allow including or not freebusy info from subscribed calendars + - now possible to set an autosave timer for draft messages + - now possible to set alarms on event invitations (#76) + +Enhancements + - updated CKEditor to version 4.4.6 and added the 'Source Area' plugin + - avoid testing for IMAP ANNOTATION when X-GUID is available (#3018) + - updated Czech, Dutch, Finnish, French, German, Polish and Spanish (Spain) translations + +Bug fixes + - fixed for privacy and categories for EAS (#3022) + - correctly set MeetingStatus for EAS on iOS devices + - Ubuntu Lucid fixes for EAS + - fixed calendar reminders for future events (#3008) + - make sure all text parts are UTF-8 re-encoded for Outlook 2013 over EAS (#3003) + - fixed task description truncation affecting WP8 phones over EAS (#3028) + +2.2.11a (2014-12-10) +-------------------- + +Bug fixes + - make sure all address books returned using EAS are GCS ones + +2.2.11 (2014-12-09) +------------------- + +New features + - sogo-tool can now be used to manage EAS metadata for all devices + +Enhancements + - improved the SAML2 documentation + - radically reduced AES memory usage + +Bug fixes + - now possible to specify the username attribute for SAML2 (SOGoSAML2LoginAttribute) (#2381) + - added support for IdP-initiated SAML2 logout (#2377) + - we now generate SAML2 metadata on the fly (#2378) + - we now handle correctly the SOGo logout when using SAML (#2376 and #2379) + - fixed freebusy lookups going off bounds for resources (#3010) + - fixed EAS clients moving mails between folders but disconnecting before receiving server's response (#2982) + +2.2.10 (2014-11-21) +------------------- + +Enhancements + - no longer leaking database passwords in the logs (#2953) + - added support for multiple calendars and address books over ActiveSync + - updated timezone information (#2968) + - updated Brazilian Portuguese, Czech, Dutch, Finnish, French, German, Hungarian, Polish, + Russian, Spanish (Argentina), and Spanish (Spain) translations + - updated CKEditor to version 4.4.5 + +Bug fixes + - fixed freebusy lookup with "Show time as busy" (#2930) + - don't escape
's in a card's note field + - fixed folder's display name when subscribing to a folder + - fixed folder's display name when the active user subscribes another user to one of her/his folders + - fixed error with new user default sorting value for the mailer module (#2952) + - fixed ActiveSync PING command flooding the server (#2940) + - fixed many interop issues with Windows Phones over ActiveSync + - fixed automatic return receipts crash when not in the recepient list (#2965) + - fixed support for Sieve folder encoding parameter (#2622) + - fixed rename of subscribed addressbooks + - sanitize strings before escaping them when using EAS + - fixed handling of event invitations on iOS/EAS with no organizer (#2978) + - fixed corrupted png files (#2975) + - improved dramatically the BSON decoding speed + - added WindowSize support for GCS collections when using EAS + - fixed IMAP search with non-ASCII folder names + - fixed extraction of email addresses when pasting text with tabs (#2945) + - fixed Outlook attachment corruption issues when using AES (#2957) + 2.2.9a (2014-09-29) ------------------- @@ -11,7 +134,7 @@ New features - support for recurrent tasks (#2160) - support for alarms on recurrent events / tasks -Enchancements +Enhancements - alarms can now be snoozed for 1 day - better iOS/Mac OS X Calendar compability regarding alarms (#1920) - force default classification over CalDAV if none is set (#2326) @@ -36,7 +159,7 @@ New features - new user settings for threads collapsing - IMAP global search support (#2670) -Enchancements +Enhancements - major refactoring of the GCS component saving code (dropped OGoContentStore) - printing calendars in colors is now possible in all views; list, daily, weekly and multicolumns - new option to print calendars events and tasks with a background color or with a border color diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile index 633f53226..d9eaf92a4 100644 --- a/OpenChange/GNUmakefile +++ b/OpenChange/GNUmakefile @@ -141,7 +141,7 @@ $(DBMSGREADER_TOOL)_OBJC_FILES += \ NSObject+PropertyList.m $(DBMSGREADER_TOOL)_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/ -lSOGo \ + -L../SoObjects/SOGo/SOGo.framework/sogo -lSOGo \ -L../SOPE/GDLContentStore/obj/ -lGDLContentStore \ -L../SOPE/NGCards/obj/ -lNGCards \ -lNGObjWeb @@ -165,12 +165,12 @@ LIBMAPISTORE_LIBS = $(shell pkg-config libmapistore --libs) -lmapiproxy -lWEExte $(MAPISTORESOGO)_INSTALL_DIR = $(DESTDIR)/$(SAMBA_LIB_DIR)/mapistore_backends $(MAPISTORESOGO)_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/ -lSOGo -lgnustep-base -lobjc -lNGObjWeb \ + -L../SoObjects/SOGo/SOGo.framework/sogo/ -lSOGo -lgnustep-base -lobjc -lNGObjWeb \ $(LIBMAPI_LIBS) \ $(LIBMAPISTORE_LIBS) $(SOGOBACKEND)_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/ -lSOGo \ + -L../SoObjects/SOGo/SOGo.framework/sogo/ -lSOGo \ $(LIBMAPI_LIBS) \ $(LIBMAPISTORE_LIBS) @@ -183,6 +183,8 @@ ADDITIONAL_INCLUDE_DIRS += \ -DBACKEND_BUNDLE_NAME="@\"$(BUNDLE_NAME)$(BUNDLE_EXTENSION)\"" \ -DSOGO_BUNDLES_DIR="@\"$(BUNDLE_INSTALL_DIR)\"" +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo + -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make include $(GNUSTEP_MAKEFILES)/library.make diff --git a/SOPE/GDLContentStore/GCSChannelManager.m b/SOPE/GDLContentStore/GCSChannelManager.m index 62a395e71..b21b230a6 100644 --- a/SOPE/GDLContentStore/GCSChannelManager.m +++ b/SOPE/GDLContentStore/GCSChannelManager.m @@ -276,7 +276,7 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60; EOAdaptorChannel *channel; GCSChannelHandle *handle; NSCalendarDate *now, *lastFailure; - NSString *urlId; + NSString *urlId, *url; channel = nil; urlId = [_url gcsURLId]; @@ -304,10 +304,10 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60; } else { + url = [NSString stringWithFormat: @"%@://%@%@", [_url scheme], [_url host], [_url path]]; if (debugPools) { - [self logWithFormat: @"DBPOOL: create new DB channel for URL: %@", - [_url absoluteString]]; + [self logWithFormat: @"DBPOOL: create new DB channel for %@", url]; } /* create channel */ @@ -330,15 +330,13 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60; if (lastFailure) { - [self logWithFormat: @"db for %@ is now back up", - [_url absoluteString]]; + [self logWithFormat: @"db for %@ is now back up", url]; [lastFailures removeObjectForKey: urlId]; } } else { - [self errorWithFormat: @"could not open channel %@ for URL: %@", - channel, [_url absoluteString]]; + [self errorWithFormat: @"could not open channel %@ for %@", channel, url]; channel = nil; [lastFailures setObject: now forKey: urlId]; [self warnWithFormat: @" will prevent opening of this" diff --git a/SOPE/GDLContentStore/GCSFolderType.m b/SOPE/GDLContentStore/GCSFolderType.m index bb99051e6..e26c988dd 100644 --- a/SOPE/GDLContentStore/GCSFolderType.m +++ b/SOPE/GDLContentStore/GCSFolderType.m @@ -20,6 +20,7 @@ */ #import +#import #import #import @@ -147,7 +148,7 @@ if ([keys count] == 0) return folderQualifier; - bindings = [_folder valuesForKeys:keys]; + bindings = [_folder dictionaryWithValuesForKeys:keys]; return [folderQualifier qualifierWithBindings:bindings requiresAllVariables:NO]; } diff --git a/SOPE/GDLContentStore/GNUmakefile b/SOPE/GDLContentStore/GNUmakefile index 84f24d0c0..b94b4057d 100644 --- a/SOPE/GDLContentStore/GNUmakefile +++ b/SOPE/GDLContentStore/GNUmakefile @@ -74,6 +74,7 @@ ifneq ($(frameworks),yes) ifneq ($(FHS_INSTALL_ROOT),) GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include endif +GNUSTEP_TARGET_LDIR=sogo include $(GNUSTEP_MAKEFILES)/library.make else include $(GNUSTEP_MAKEFILES)/framework.make diff --git a/SOPE/NGCards/CardGroup.m b/SOPE/NGCards/CardGroup.m index c9ecfb1f3..b3c21e9d9 100644 --- a/SOPE/NGCards/CardGroup.m +++ b/SOPE/NGCards/CardGroup.m @@ -59,8 +59,10 @@ static NGCardsSaxHandler *sax = nil; [parser setErrorHandler:sax]; } else - NSLog(@"ERROR(%s): did not find a parser for text/x-vcard!", - __PRETTY_FUNCTION__); + { + //NSLog(@"ERROR(%s): did not find a parser for text/x-vcard!", + // __PRETTY_FUNCTION__); + } } return parser; @@ -170,8 +172,8 @@ static NGCardsSaxHandler *sax = nil; { if (![aChild isKindOfClass: mappedClass]) { - NSLog (@"warning: new child to entity '%@': '%@' converted to '%@'", - tag, childTag, NSStringFromClass(mappedClass)); + //NSLog (@"warning: new child to entity '%@': '%@' converted to '%@'", + // tag, childTag, NSStringFromClass(mappedClass)); newChild = [aChild elementWithClass: mappedClass]; } } diff --git a/SOPE/NGCards/GNUmakefile b/SOPE/NGCards/GNUmakefile index 90f75848a..31cfdd836 100644 --- a/SOPE/NGCards/GNUmakefile +++ b/SOPE/NGCards/GNUmakefile @@ -131,6 +131,7 @@ ifneq ($(frameworks),yes) ifneq ($(FHS_INSTALL_ROOT),) GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include endif +GNUSTEP_TARGET_LDIR=sogo include $(GNUSTEP_MAKEFILES)/library.make else include $(GNUSTEP_MAKEFILES)/framework.make diff --git a/SOPE/NGCards/IcalResponse.m b/SOPE/NGCards/IcalResponse.m index 843fe43e1..0caddae52 100644 --- a/SOPE/NGCards/IcalResponse.m +++ b/SOPE/NGCards/IcalResponse.m @@ -54,7 +54,7 @@ - (BOOL)appendLine:(NSString *)_line { if (self->isFinished) { - NSLog(@"WARNING[%s]: already finished!", __PRETTY_FUNCTION__); + //NSLog(@"WARNING[%s]: already finished!", __PRETTY_FUNCTION__); return NO; } // limit length to 75 chars diff --git a/SOPE/NGCards/NSCalendarDate+ICal.m b/SOPE/NGCards/NSCalendarDate+ICal.m index 3363d2f3b..4e6d529b6 100644 --- a/SOPE/NGCards/NSCalendarDate+ICal.m +++ b/SOPE/NGCards/NSCalendarDate+ICal.m @@ -77,8 +77,8 @@ static NSString *gmtcalfmt = @"%Y%m%dT%H%M%SZ"; return [self icalStringInGMT]; else { /* not in GMT */ - NSLog(@"WARNING(%s): arbitary timezones not supported yet: %@", - __PRETTY_FUNCTION__, _tz); + //NSLog(@"WARNING(%s): arbitary timezones not supported yet: %@", + // __PRETTY_FUNCTION__, _tz); return [self icalStringInGMT]; } } diff --git a/SOPE/NGCards/NSString+NGCards.m b/SOPE/NGCards/NSString+NGCards.m index 8eef43074..9e851ac2e 100644 --- a/SOPE/NGCards/NSString+NGCards.m +++ b/SOPE/NGCards/NSString+NGCards.m @@ -276,7 +276,9 @@ } } else - NSLog(@"Cannot parse iCal duration value: '%@'", self); + { + //NSLog(@"Cannot parse iCal duration value: '%@'", self); + } if (isNegative) ti = -ti; diff --git a/SOPE/NGCards/TimeZones/Africa/Abidjan.ics b/SOPE/NGCards/TimeZones/Africa/Abidjan.ics index b4a41bae5..2d0886e72 100644 --- a/SOPE/NGCards/TimeZones/Africa/Abidjan.ics +++ b/SOPE/NGCards/TimeZones/Africa/Abidjan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Abidjan diff --git a/SOPE/NGCards/TimeZones/Africa/Accra.ics b/SOPE/NGCards/TimeZones/Africa/Accra.ics index fbe1a81f4..089fb6353 100644 --- a/SOPE/NGCards/TimeZones/Africa/Accra.ics +++ b/SOPE/NGCards/TimeZones/Africa/Accra.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Accra diff --git a/SOPE/NGCards/TimeZones/Africa/Addis_Ababa.ics b/SOPE/NGCards/TimeZones/Africa/Addis_Ababa.ics index b9d52ae7d..66b60542d 100644 --- a/SOPE/NGCards/TimeZones/Africa/Addis_Ababa.ics +++ b/SOPE/NGCards/TimeZones/Africa/Addis_Ababa.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Addis_Ababa diff --git a/SOPE/NGCards/TimeZones/Africa/Algiers.ics b/SOPE/NGCards/TimeZones/Africa/Algiers.ics index e08496a8a..13b2d9e5b 100644 --- a/SOPE/NGCards/TimeZones/Africa/Algiers.ics +++ b/SOPE/NGCards/TimeZones/Africa/Algiers.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Algiers diff --git a/SOPE/NGCards/TimeZones/Africa/Asmara.ics b/SOPE/NGCards/TimeZones/Africa/Asmara.ics index 192c874df..a456a3b7d 100644 --- a/SOPE/NGCards/TimeZones/Africa/Asmara.ics +++ b/SOPE/NGCards/TimeZones/Africa/Asmara.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Asmara diff --git a/SOPE/NGCards/TimeZones/Africa/Bamako.ics b/SOPE/NGCards/TimeZones/Africa/Bamako.ics index eb06bf6b0..f8e989c75 100644 --- a/SOPE/NGCards/TimeZones/Africa/Bamako.ics +++ b/SOPE/NGCards/TimeZones/Africa/Bamako.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Bamako diff --git a/SOPE/NGCards/TimeZones/Africa/Bangui.ics b/SOPE/NGCards/TimeZones/Africa/Bangui.ics index dd2902b84..03e755b73 100644 --- a/SOPE/NGCards/TimeZones/Africa/Bangui.ics +++ b/SOPE/NGCards/TimeZones/Africa/Bangui.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Bangui diff --git a/SOPE/NGCards/TimeZones/Africa/Banjul.ics b/SOPE/NGCards/TimeZones/Africa/Banjul.ics index a41cc58f9..e9d579e60 100644 --- a/SOPE/NGCards/TimeZones/Africa/Banjul.ics +++ b/SOPE/NGCards/TimeZones/Africa/Banjul.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Banjul diff --git a/SOPE/NGCards/TimeZones/Africa/Bissau.ics b/SOPE/NGCards/TimeZones/Africa/Bissau.ics index 1e90a3eab..14fb6511f 100644 --- a/SOPE/NGCards/TimeZones/Africa/Bissau.ics +++ b/SOPE/NGCards/TimeZones/Africa/Bissau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Bissau diff --git a/SOPE/NGCards/TimeZones/Africa/Blantyre.ics b/SOPE/NGCards/TimeZones/Africa/Blantyre.ics index 26f666278..98dc53b74 100644 --- a/SOPE/NGCards/TimeZones/Africa/Blantyre.ics +++ b/SOPE/NGCards/TimeZones/Africa/Blantyre.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Blantyre diff --git a/SOPE/NGCards/TimeZones/Africa/Brazzaville.ics b/SOPE/NGCards/TimeZones/Africa/Brazzaville.ics index 40bd02fd2..5dcffaf53 100644 --- a/SOPE/NGCards/TimeZones/Africa/Brazzaville.ics +++ b/SOPE/NGCards/TimeZones/Africa/Brazzaville.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Brazzaville diff --git a/SOPE/NGCards/TimeZones/Africa/Bujumbura.ics b/SOPE/NGCards/TimeZones/Africa/Bujumbura.ics index 0b8471e74..214abc48e 100644 --- a/SOPE/NGCards/TimeZones/Africa/Bujumbura.ics +++ b/SOPE/NGCards/TimeZones/Africa/Bujumbura.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Bujumbura diff --git a/SOPE/NGCards/TimeZones/Africa/Cairo.ics b/SOPE/NGCards/TimeZones/Africa/Cairo.ics index d7ada8472..cb946a0ac 100644 --- a/SOPE/NGCards/TimeZones/Africa/Cairo.ics +++ b/SOPE/NGCards/TimeZones/Africa/Cairo.ics @@ -1,14 +1,22 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Cairo X-LIC-LOCATION:Africa/Cairo BEGIN:STANDARD -TZOFFSETFROM:+0200 +TZOFFSETFROM:+0300 TZOFFSETTO:+0200 TZNAME:EET -DTSTART:19700101T000000 +DTSTART:19700924T235959 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1TH END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0300 +TZOFFSETTO:+0300 +TZNAME:EEST +DTSTART:19700424T010000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1FR +END:DAYLIGHT END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Africa/Casablanca.ics b/SOPE/NGCards/TimeZones/Africa/Casablanca.ics index 37b853064..2424b03fd 100644 --- a/SOPE/NGCards/TimeZones/Africa/Casablanca.ics +++ b/SOPE/NGCards/TimeZones/Africa/Casablanca.ics @@ -1,22 +1,22 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Casablanca X-LIC-LOCATION:Africa/Casablanca -BEGIN:DAYLIGHT -TZOFFSETFROM:+0000 -TZOFFSETTO:+0100 -TZNAME:WEST -DTSTART:19700426T020000 -RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU -END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0100 TZOFFSETTO:+0000 TZNAME:WET -DTSTART:19700927T030000 -RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +TZNAME:WEST +DTSTART:19700329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Africa/Ceuta.ics b/SOPE/NGCards/TimeZones/Africa/Ceuta.ics index 526241708..237024157 100644 --- a/SOPE/NGCards/TimeZones/Africa/Ceuta.ics +++ b/SOPE/NGCards/TimeZones/Africa/Ceuta.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Ceuta diff --git a/SOPE/NGCards/TimeZones/Africa/Conakry.ics b/SOPE/NGCards/TimeZones/Africa/Conakry.ics index 4ed6bc0c5..72a68faa2 100644 --- a/SOPE/NGCards/TimeZones/Africa/Conakry.ics +++ b/SOPE/NGCards/TimeZones/Africa/Conakry.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Conakry diff --git a/SOPE/NGCards/TimeZones/Africa/Dakar.ics b/SOPE/NGCards/TimeZones/Africa/Dakar.ics index 2485cf464..eb55e58ba 100644 --- a/SOPE/NGCards/TimeZones/Africa/Dakar.ics +++ b/SOPE/NGCards/TimeZones/Africa/Dakar.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Dakar diff --git a/SOPE/NGCards/TimeZones/Africa/Dar_es_Salaam.ics b/SOPE/NGCards/TimeZones/Africa/Dar_es_Salaam.ics index c45ed6520..154b826ba 100644 --- a/SOPE/NGCards/TimeZones/Africa/Dar_es_Salaam.ics +++ b/SOPE/NGCards/TimeZones/Africa/Dar_es_Salaam.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Dar_es_Salaam diff --git a/SOPE/NGCards/TimeZones/Africa/Djibouti.ics b/SOPE/NGCards/TimeZones/Africa/Djibouti.ics index 82cef5d55..7fefeb4b0 100644 --- a/SOPE/NGCards/TimeZones/Africa/Djibouti.ics +++ b/SOPE/NGCards/TimeZones/Africa/Djibouti.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Djibouti diff --git a/SOPE/NGCards/TimeZones/Africa/Douala.ics b/SOPE/NGCards/TimeZones/Africa/Douala.ics index 8a3a7b82e..249062f5f 100644 --- a/SOPE/NGCards/TimeZones/Africa/Douala.ics +++ b/SOPE/NGCards/TimeZones/Africa/Douala.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Douala diff --git a/SOPE/NGCards/TimeZones/Africa/El_Aaiun.ics b/SOPE/NGCards/TimeZones/Africa/El_Aaiun.ics index daa9fa21f..18bb12608 100644 --- a/SOPE/NGCards/TimeZones/Africa/El_Aaiun.ics +++ b/SOPE/NGCards/TimeZones/Africa/El_Aaiun.ics @@ -1,14 +1,22 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/El_Aaiun X-LIC-LOCATION:Africa/El_Aaiun BEGIN:STANDARD -TZOFFSETFROM:+0000 +TZOFFSETFROM:+0100 TZOFFSETTO:+0000 TZNAME:WET -DTSTART:19700101T000000 +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +TZNAME:WEST +DTSTART:19700329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Africa/Freetown.ics b/SOPE/NGCards/TimeZones/Africa/Freetown.ics index 2b689ba56..c7daed840 100644 --- a/SOPE/NGCards/TimeZones/Africa/Freetown.ics +++ b/SOPE/NGCards/TimeZones/Africa/Freetown.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Freetown diff --git a/SOPE/NGCards/TimeZones/Africa/Gaborone.ics b/SOPE/NGCards/TimeZones/Africa/Gaborone.ics index 27a91098f..0f94ca8bd 100644 --- a/SOPE/NGCards/TimeZones/Africa/Gaborone.ics +++ b/SOPE/NGCards/TimeZones/Africa/Gaborone.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Gaborone diff --git a/SOPE/NGCards/TimeZones/Africa/Harare.ics b/SOPE/NGCards/TimeZones/Africa/Harare.ics index 7fe0c6302..543e49ad1 100644 --- a/SOPE/NGCards/TimeZones/Africa/Harare.ics +++ b/SOPE/NGCards/TimeZones/Africa/Harare.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Harare diff --git a/SOPE/NGCards/TimeZones/Africa/Johannesburg.ics b/SOPE/NGCards/TimeZones/Africa/Johannesburg.ics index 57f55cdc7..91edd0aab 100644 --- a/SOPE/NGCards/TimeZones/Africa/Johannesburg.ics +++ b/SOPE/NGCards/TimeZones/Africa/Johannesburg.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Johannesburg diff --git a/SOPE/NGCards/TimeZones/Africa/Juba.ics b/SOPE/NGCards/TimeZones/Africa/Juba.ics index 02563da06..99f7b0002 100644 --- a/SOPE/NGCards/TimeZones/Africa/Juba.ics +++ b/SOPE/NGCards/TimeZones/Africa/Juba.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Juba diff --git a/SOPE/NGCards/TimeZones/Africa/Kampala.ics b/SOPE/NGCards/TimeZones/Africa/Kampala.ics index b64e6654f..96ad293b3 100644 --- a/SOPE/NGCards/TimeZones/Africa/Kampala.ics +++ b/SOPE/NGCards/TimeZones/Africa/Kampala.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Kampala diff --git a/SOPE/NGCards/TimeZones/Africa/Khartoum.ics b/SOPE/NGCards/TimeZones/Africa/Khartoum.ics index 3754dfb68..75badb8b0 100644 --- a/SOPE/NGCards/TimeZones/Africa/Khartoum.ics +++ b/SOPE/NGCards/TimeZones/Africa/Khartoum.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Khartoum diff --git a/SOPE/NGCards/TimeZones/Africa/Kigali.ics b/SOPE/NGCards/TimeZones/Africa/Kigali.ics index 5a170e256..0226b6a12 100644 --- a/SOPE/NGCards/TimeZones/Africa/Kigali.ics +++ b/SOPE/NGCards/TimeZones/Africa/Kigali.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Kigali diff --git a/SOPE/NGCards/TimeZones/Africa/Kinshasa.ics b/SOPE/NGCards/TimeZones/Africa/Kinshasa.ics index 232d7dad0..99221a229 100644 --- a/SOPE/NGCards/TimeZones/Africa/Kinshasa.ics +++ b/SOPE/NGCards/TimeZones/Africa/Kinshasa.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Kinshasa diff --git a/SOPE/NGCards/TimeZones/Africa/Lagos.ics b/SOPE/NGCards/TimeZones/Africa/Lagos.ics index 19b6f1ea5..c2486ac7f 100644 --- a/SOPE/NGCards/TimeZones/Africa/Lagos.ics +++ b/SOPE/NGCards/TimeZones/Africa/Lagos.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Lagos diff --git a/SOPE/NGCards/TimeZones/Africa/Libreville.ics b/SOPE/NGCards/TimeZones/Africa/Libreville.ics index 1845ba537..2765b0c6f 100644 --- a/SOPE/NGCards/TimeZones/Africa/Libreville.ics +++ b/SOPE/NGCards/TimeZones/Africa/Libreville.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Libreville diff --git a/SOPE/NGCards/TimeZones/Africa/Lome.ics b/SOPE/NGCards/TimeZones/Africa/Lome.ics index 6549bb42a..227946eed 100644 --- a/SOPE/NGCards/TimeZones/Africa/Lome.ics +++ b/SOPE/NGCards/TimeZones/Africa/Lome.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Lome diff --git a/SOPE/NGCards/TimeZones/Africa/Luanda.ics b/SOPE/NGCards/TimeZones/Africa/Luanda.ics index 0de494b95..324a08b53 100644 --- a/SOPE/NGCards/TimeZones/Africa/Luanda.ics +++ b/SOPE/NGCards/TimeZones/Africa/Luanda.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Luanda diff --git a/SOPE/NGCards/TimeZones/Africa/Lubumbashi.ics b/SOPE/NGCards/TimeZones/Africa/Lubumbashi.ics index 5c8ec090a..c5703a198 100644 --- a/SOPE/NGCards/TimeZones/Africa/Lubumbashi.ics +++ b/SOPE/NGCards/TimeZones/Africa/Lubumbashi.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Lubumbashi diff --git a/SOPE/NGCards/TimeZones/Africa/Lusaka.ics b/SOPE/NGCards/TimeZones/Africa/Lusaka.ics index b3e362b8c..5d792086e 100644 --- a/SOPE/NGCards/TimeZones/Africa/Lusaka.ics +++ b/SOPE/NGCards/TimeZones/Africa/Lusaka.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Lusaka diff --git a/SOPE/NGCards/TimeZones/Africa/Malabo.ics b/SOPE/NGCards/TimeZones/Africa/Malabo.ics index 2fbef4fbf..a3f0ab84c 100644 --- a/SOPE/NGCards/TimeZones/Africa/Malabo.ics +++ b/SOPE/NGCards/TimeZones/Africa/Malabo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Malabo diff --git a/SOPE/NGCards/TimeZones/Africa/Maputo.ics b/SOPE/NGCards/TimeZones/Africa/Maputo.ics index 30df05d2b..40e26f1c7 100644 --- a/SOPE/NGCards/TimeZones/Africa/Maputo.ics +++ b/SOPE/NGCards/TimeZones/Africa/Maputo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Maputo diff --git a/SOPE/NGCards/TimeZones/Africa/Maseru.ics b/SOPE/NGCards/TimeZones/Africa/Maseru.ics index d9f6fa83c..10a504381 100644 --- a/SOPE/NGCards/TimeZones/Africa/Maseru.ics +++ b/SOPE/NGCards/TimeZones/Africa/Maseru.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Maseru diff --git a/SOPE/NGCards/TimeZones/Africa/Mbabane.ics b/SOPE/NGCards/TimeZones/Africa/Mbabane.ics index c6e73fa22..8b2a2da1e 100644 --- a/SOPE/NGCards/TimeZones/Africa/Mbabane.ics +++ b/SOPE/NGCards/TimeZones/Africa/Mbabane.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Mbabane diff --git a/SOPE/NGCards/TimeZones/Africa/Mogadishu.ics b/SOPE/NGCards/TimeZones/Africa/Mogadishu.ics index 70b8639e8..c25678f5b 100644 --- a/SOPE/NGCards/TimeZones/Africa/Mogadishu.ics +++ b/SOPE/NGCards/TimeZones/Africa/Mogadishu.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Mogadishu diff --git a/SOPE/NGCards/TimeZones/Africa/Monrovia.ics b/SOPE/NGCards/TimeZones/Africa/Monrovia.ics index 0f2d6a54e..c509dd137 100644 --- a/SOPE/NGCards/TimeZones/Africa/Monrovia.ics +++ b/SOPE/NGCards/TimeZones/Africa/Monrovia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Monrovia diff --git a/SOPE/NGCards/TimeZones/Africa/Nairobi.ics b/SOPE/NGCards/TimeZones/Africa/Nairobi.ics index 552822a8f..167681055 100644 --- a/SOPE/NGCards/TimeZones/Africa/Nairobi.ics +++ b/SOPE/NGCards/TimeZones/Africa/Nairobi.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Nairobi diff --git a/SOPE/NGCards/TimeZones/Africa/Ndjamena.ics b/SOPE/NGCards/TimeZones/Africa/Ndjamena.ics index b536d06c3..77316d953 100644 --- a/SOPE/NGCards/TimeZones/Africa/Ndjamena.ics +++ b/SOPE/NGCards/TimeZones/Africa/Ndjamena.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Ndjamena diff --git a/SOPE/NGCards/TimeZones/Africa/Niamey.ics b/SOPE/NGCards/TimeZones/Africa/Niamey.ics index fa4d2e567..b8cba64d7 100644 --- a/SOPE/NGCards/TimeZones/Africa/Niamey.ics +++ b/SOPE/NGCards/TimeZones/Africa/Niamey.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Niamey diff --git a/SOPE/NGCards/TimeZones/Africa/Nouakchott.ics b/SOPE/NGCards/TimeZones/Africa/Nouakchott.ics index 8d31a7c36..c8f8041d0 100644 --- a/SOPE/NGCards/TimeZones/Africa/Nouakchott.ics +++ b/SOPE/NGCards/TimeZones/Africa/Nouakchott.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Nouakchott diff --git a/SOPE/NGCards/TimeZones/Africa/Ouagadougou.ics b/SOPE/NGCards/TimeZones/Africa/Ouagadougou.ics index 5b6bf4c0c..ace03e7ad 100644 --- a/SOPE/NGCards/TimeZones/Africa/Ouagadougou.ics +++ b/SOPE/NGCards/TimeZones/Africa/Ouagadougou.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Ouagadougou diff --git a/SOPE/NGCards/TimeZones/Africa/Porto-Novo.ics b/SOPE/NGCards/TimeZones/Africa/Porto-Novo.ics index 1361b6cb5..d85ecc0e2 100644 --- a/SOPE/NGCards/TimeZones/Africa/Porto-Novo.ics +++ b/SOPE/NGCards/TimeZones/Africa/Porto-Novo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Porto-Novo diff --git a/SOPE/NGCards/TimeZones/Africa/Sao_Tome.ics b/SOPE/NGCards/TimeZones/Africa/Sao_Tome.ics index 9c85867e4..75313f5d0 100644 --- a/SOPE/NGCards/TimeZones/Africa/Sao_Tome.ics +++ b/SOPE/NGCards/TimeZones/Africa/Sao_Tome.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Sao_Tome diff --git a/SOPE/NGCards/TimeZones/Africa/Tripoli.ics b/SOPE/NGCards/TimeZones/Africa/Tripoli.ics index d3d9850bf..11493be4b 100644 --- a/SOPE/NGCards/TimeZones/Africa/Tripoli.ics +++ b/SOPE/NGCards/TimeZones/Africa/Tripoli.ics @@ -1,22 +1,14 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Tripoli X-LIC-LOCATION:Africa/Tripoli -BEGIN:DAYLIGHT -TZOFFSETFROM:+0100 -TZOFFSETTO:+0200 -TZNAME:CEST -DTSTART:19700327T010000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1FR -END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 -TZOFFSETTO:+0100 -TZNAME:CET -DTSTART:19701030T020000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1FR +TZOFFSETTO:+0200 +TZNAME:EET +DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Africa/Tunis.ics b/SOPE/NGCards/TimeZones/Africa/Tunis.ics index cc54ccc3d..122673252 100644 --- a/SOPE/NGCards/TimeZones/Africa/Tunis.ics +++ b/SOPE/NGCards/TimeZones/Africa/Tunis.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Tunis diff --git a/SOPE/NGCards/TimeZones/Africa/Windhoek.ics b/SOPE/NGCards/TimeZones/Africa/Windhoek.ics index c8c875f4f..24dcb86cf 100644 --- a/SOPE/NGCards/TimeZones/Africa/Windhoek.ics +++ b/SOPE/NGCards/TimeZones/Africa/Windhoek.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Africa/Windhoek diff --git a/SOPE/NGCards/TimeZones/America/Adak.ics b/SOPE/NGCards/TimeZones/America/Adak.ics index e379b2438..3fc727426 100644 --- a/SOPE/NGCards/TimeZones/America/Adak.ics +++ b/SOPE/NGCards/TimeZones/America/Adak.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Adak diff --git a/SOPE/NGCards/TimeZones/America/Anchorage.ics b/SOPE/NGCards/TimeZones/America/Anchorage.ics index 2fb246172..a34fc0846 100644 --- a/SOPE/NGCards/TimeZones/America/Anchorage.ics +++ b/SOPE/NGCards/TimeZones/America/Anchorage.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Anchorage diff --git a/SOPE/NGCards/TimeZones/America/Anguilla.ics b/SOPE/NGCards/TimeZones/America/Anguilla.ics index d3ab3cd33..6e60dfcbc 100644 --- a/SOPE/NGCards/TimeZones/America/Anguilla.ics +++ b/SOPE/NGCards/TimeZones/America/Anguilla.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Anguilla diff --git a/SOPE/NGCards/TimeZones/America/Antigua.ics b/SOPE/NGCards/TimeZones/America/Antigua.ics index 6db7cec91..9da6564bb 100644 --- a/SOPE/NGCards/TimeZones/America/Antigua.ics +++ b/SOPE/NGCards/TimeZones/America/Antigua.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Antigua diff --git a/SOPE/NGCards/TimeZones/America/Araguaina.ics b/SOPE/NGCards/TimeZones/America/Araguaina.ics index 9a9bf4af2..0bd4ae909 100644 --- a/SOPE/NGCards/TimeZones/America/Araguaina.ics +++ b/SOPE/NGCards/TimeZones/America/Araguaina.ics @@ -1,22 +1,14 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Araguaina X-LIC-LOCATION:America/Araguaina -BEGIN:DAYLIGHT -TZOFFSETFROM:-0300 -TZOFFSETTO:-0200 -TZNAME:BRST -DTSTART:19701018T000000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=3SU -END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:-0300 TZOFFSETTO:-0300 TZNAME:BRT -DTSTART:19700215T000000 -RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=3SU +DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Buenos_Aires.ics b/SOPE/NGCards/TimeZones/America/Argentina/Buenos_Aires.ics index 55fef3e99..61b28250a 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Buenos_Aires.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Buenos_Aires.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Buenos_Aires diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Catamarca.ics b/SOPE/NGCards/TimeZones/America/Argentina/Catamarca.ics index cbcc43fdd..f24fce6bb 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Catamarca.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Catamarca.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Catamarca diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Cordoba.ics b/SOPE/NGCards/TimeZones/America/Argentina/Cordoba.ics index 808afe05e..963a40b9b 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Cordoba.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Cordoba.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Cordoba diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Jujuy.ics b/SOPE/NGCards/TimeZones/America/Argentina/Jujuy.ics index 753f0132a..44de9c6b4 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Jujuy.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Jujuy.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Jujuy diff --git a/SOPE/NGCards/TimeZones/America/Argentina/La_Rioja.ics b/SOPE/NGCards/TimeZones/America/Argentina/La_Rioja.ics index a8f88c0d9..da14dc26d 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/La_Rioja.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/La_Rioja.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/La_Rioja diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Mendoza.ics b/SOPE/NGCards/TimeZones/America/Argentina/Mendoza.ics index 75e30b63f..1793f5084 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Mendoza.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Mendoza.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Mendoza diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Rio_Gallegos.ics b/SOPE/NGCards/TimeZones/America/Argentina/Rio_Gallegos.ics index 4662a010f..497600fc4 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Rio_Gallegos.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Rio_Gallegos.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Rio_Gallegos diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Salta.ics b/SOPE/NGCards/TimeZones/America/Argentina/Salta.ics index 156724be8..79a267dee 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Salta.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Salta.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Salta diff --git a/SOPE/NGCards/TimeZones/America/Argentina/San_Juan.ics b/SOPE/NGCards/TimeZones/America/Argentina/San_Juan.ics index 4113f2d58..cc1ffd11c 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/San_Juan.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/San_Juan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/San_Juan diff --git a/SOPE/NGCards/TimeZones/America/Argentina/San_Luis.ics b/SOPE/NGCards/TimeZones/America/Argentina/San_Luis.ics index 336916215..018d19757 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/San_Luis.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/San_Luis.ics @@ -1,13 +1,13 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/San_Luis X-LIC-LOCATION:America/Argentina/San_Luis BEGIN:STANDARD -TZOFFSETFROM:-0400 -TZOFFSETTO:-0400 -TZNAME:WART +TZOFFSETFROM:-0300 +TZOFFSETTO:-0300 +TZNAME:ART DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Tucuman.ics b/SOPE/NGCards/TimeZones/America/Argentina/Tucuman.ics index d99d46e2c..eb16b9ca3 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Tucuman.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Tucuman.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Tucuman diff --git a/SOPE/NGCards/TimeZones/America/Argentina/Ushuaia.ics b/SOPE/NGCards/TimeZones/America/Argentina/Ushuaia.ics index 9b6ccd44b..cac913d74 100644 --- a/SOPE/NGCards/TimeZones/America/Argentina/Ushuaia.ics +++ b/SOPE/NGCards/TimeZones/America/Argentina/Ushuaia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Argentina/Ushuaia diff --git a/SOPE/NGCards/TimeZones/America/Aruba.ics b/SOPE/NGCards/TimeZones/America/Aruba.ics index 34200cbca..e4cd0ea60 100644 --- a/SOPE/NGCards/TimeZones/America/Aruba.ics +++ b/SOPE/NGCards/TimeZones/America/Aruba.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Aruba diff --git a/SOPE/NGCards/TimeZones/America/Asuncion.ics b/SOPE/NGCards/TimeZones/America/Asuncion.ics index 267a9441f..fa6aa014b 100644 --- a/SOPE/NGCards/TimeZones/America/Asuncion.ics +++ b/SOPE/NGCards/TimeZones/America/Asuncion.ics @@ -1,16 +1,9 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Asuncion X-LIC-LOCATION:America/Asuncion -BEGIN:STANDARD -TZOFFSETFROM:-0300 -TZOFFSETTO:-0400 -TZNAME:PYT -DTSTART:19700412T000000 -RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=2SU -END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:-0400 TZOFFSETTO:-0300 @@ -18,5 +11,12 @@ TZNAME:PYST DTSTART:19701004T000000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:-0300 +TZOFFSETTO:-0400 +TZNAME:PYT +DTSTART:19700322T000000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=4SU +END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/America/Atikokan.ics b/SOPE/NGCards/TimeZones/America/Atikokan.ics index 1ed82ff8b..c2442a65a 100644 --- a/SOPE/NGCards/TimeZones/America/Atikokan.ics +++ b/SOPE/NGCards/TimeZones/America/Atikokan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Atikokan diff --git a/SOPE/NGCards/TimeZones/America/Bahia.ics b/SOPE/NGCards/TimeZones/America/Bahia.ics index e47aa2f1d..1c8ae0570 100644 --- a/SOPE/NGCards/TimeZones/America/Bahia.ics +++ b/SOPE/NGCards/TimeZones/America/Bahia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Bahia diff --git a/SOPE/NGCards/TimeZones/America/Bahia_Banderas.ics b/SOPE/NGCards/TimeZones/America/Bahia_Banderas.ics index 0915e90e6..c147b0731 100644 --- a/SOPE/NGCards/TimeZones/America/Bahia_Banderas.ics +++ b/SOPE/NGCards/TimeZones/America/Bahia_Banderas.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Bahia_Banderas diff --git a/SOPE/NGCards/TimeZones/America/Barbados.ics b/SOPE/NGCards/TimeZones/America/Barbados.ics index acad2983c..7c745bb3b 100644 --- a/SOPE/NGCards/TimeZones/America/Barbados.ics +++ b/SOPE/NGCards/TimeZones/America/Barbados.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Barbados diff --git a/SOPE/NGCards/TimeZones/America/Belem.ics b/SOPE/NGCards/TimeZones/America/Belem.ics index a459b609d..adea76075 100644 --- a/SOPE/NGCards/TimeZones/America/Belem.ics +++ b/SOPE/NGCards/TimeZones/America/Belem.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Belem diff --git a/SOPE/NGCards/TimeZones/America/Belize.ics b/SOPE/NGCards/TimeZones/America/Belize.ics index dfaccb159..a52b7a6fa 100644 --- a/SOPE/NGCards/TimeZones/America/Belize.ics +++ b/SOPE/NGCards/TimeZones/America/Belize.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Belize diff --git a/SOPE/NGCards/TimeZones/America/Blanc-Sablon.ics b/SOPE/NGCards/TimeZones/America/Blanc-Sablon.ics index 02bee4e1e..2c59dd830 100644 --- a/SOPE/NGCards/TimeZones/America/Blanc-Sablon.ics +++ b/SOPE/NGCards/TimeZones/America/Blanc-Sablon.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Blanc-Sablon diff --git a/SOPE/NGCards/TimeZones/America/Boa_Vista.ics b/SOPE/NGCards/TimeZones/America/Boa_Vista.ics index 0e3566b6f..54ea7bd8a 100644 --- a/SOPE/NGCards/TimeZones/America/Boa_Vista.ics +++ b/SOPE/NGCards/TimeZones/America/Boa_Vista.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Boa_Vista diff --git a/SOPE/NGCards/TimeZones/America/Bogota.ics b/SOPE/NGCards/TimeZones/America/Bogota.ics index c2227451f..c2f04f930 100644 --- a/SOPE/NGCards/TimeZones/America/Bogota.ics +++ b/SOPE/NGCards/TimeZones/America/Bogota.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Bogota diff --git a/SOPE/NGCards/TimeZones/America/Boise.ics b/SOPE/NGCards/TimeZones/America/Boise.ics index 7ead8d0e3..be1d85579 100644 --- a/SOPE/NGCards/TimeZones/America/Boise.ics +++ b/SOPE/NGCards/TimeZones/America/Boise.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Boise diff --git a/SOPE/NGCards/TimeZones/America/Cambridge_Bay.ics b/SOPE/NGCards/TimeZones/America/Cambridge_Bay.ics index 7471ac2de..494f653cc 100644 --- a/SOPE/NGCards/TimeZones/America/Cambridge_Bay.ics +++ b/SOPE/NGCards/TimeZones/America/Cambridge_Bay.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Cambridge_Bay diff --git a/SOPE/NGCards/TimeZones/America/Campo_Grande.ics b/SOPE/NGCards/TimeZones/America/Campo_Grande.ics index 5c13e8dd6..539ba63d6 100644 --- a/SOPE/NGCards/TimeZones/America/Campo_Grande.ics +++ b/SOPE/NGCards/TimeZones/America/Campo_Grande.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Campo_Grande diff --git a/SOPE/NGCards/TimeZones/America/Cancun.ics b/SOPE/NGCards/TimeZones/America/Cancun.ics index 0950198db..4d5ce11a9 100644 --- a/SOPE/NGCards/TimeZones/America/Cancun.ics +++ b/SOPE/NGCards/TimeZones/America/Cancun.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Cancun diff --git a/SOPE/NGCards/TimeZones/America/Caracas.ics b/SOPE/NGCards/TimeZones/America/Caracas.ics index 72457440d..8dfe62b36 100644 --- a/SOPE/NGCards/TimeZones/America/Caracas.ics +++ b/SOPE/NGCards/TimeZones/America/Caracas.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Caracas diff --git a/SOPE/NGCards/TimeZones/America/Cayenne.ics b/SOPE/NGCards/TimeZones/America/Cayenne.ics index 0589583be..d17dacfca 100644 --- a/SOPE/NGCards/TimeZones/America/Cayenne.ics +++ b/SOPE/NGCards/TimeZones/America/Cayenne.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Cayenne diff --git a/SOPE/NGCards/TimeZones/America/Cayman.ics b/SOPE/NGCards/TimeZones/America/Cayman.ics index a0f44a40a..1671f0a90 100644 --- a/SOPE/NGCards/TimeZones/America/Cayman.ics +++ b/SOPE/NGCards/TimeZones/America/Cayman.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Cayman diff --git a/SOPE/NGCards/TimeZones/America/Chicago.ics b/SOPE/NGCards/TimeZones/America/Chicago.ics index 305323687..647e7b591 100644 --- a/SOPE/NGCards/TimeZones/America/Chicago.ics +++ b/SOPE/NGCards/TimeZones/America/Chicago.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Chicago diff --git a/SOPE/NGCards/TimeZones/America/Chihuahua.ics b/SOPE/NGCards/TimeZones/America/Chihuahua.ics index a6a8ed52c..be2e7c453 100644 --- a/SOPE/NGCards/TimeZones/America/Chihuahua.ics +++ b/SOPE/NGCards/TimeZones/America/Chihuahua.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Chihuahua diff --git a/SOPE/NGCards/TimeZones/America/Costa_Rica.ics b/SOPE/NGCards/TimeZones/America/Costa_Rica.ics index 2ef1f13c1..1d71073f0 100644 --- a/SOPE/NGCards/TimeZones/America/Costa_Rica.ics +++ b/SOPE/NGCards/TimeZones/America/Costa_Rica.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Costa_Rica diff --git a/SOPE/NGCards/TimeZones/America/Creston.ics b/SOPE/NGCards/TimeZones/America/Creston.ics index 5c18503ca..6bf5af18f 100644 --- a/SOPE/NGCards/TimeZones/America/Creston.ics +++ b/SOPE/NGCards/TimeZones/America/Creston.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Creston diff --git a/SOPE/NGCards/TimeZones/America/Cuiaba.ics b/SOPE/NGCards/TimeZones/America/Cuiaba.ics index d1f808753..ea7004e99 100644 --- a/SOPE/NGCards/TimeZones/America/Cuiaba.ics +++ b/SOPE/NGCards/TimeZones/America/Cuiaba.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Cuiaba diff --git a/SOPE/NGCards/TimeZones/America/Curacao.ics b/SOPE/NGCards/TimeZones/America/Curacao.ics index fc3148201..3a930c39d 100644 --- a/SOPE/NGCards/TimeZones/America/Curacao.ics +++ b/SOPE/NGCards/TimeZones/America/Curacao.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Curacao diff --git a/SOPE/NGCards/TimeZones/America/Danmarkshavn.ics b/SOPE/NGCards/TimeZones/America/Danmarkshavn.ics index aa9c3f0f3..8505200ea 100644 --- a/SOPE/NGCards/TimeZones/America/Danmarkshavn.ics +++ b/SOPE/NGCards/TimeZones/America/Danmarkshavn.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Danmarkshavn diff --git a/SOPE/NGCards/TimeZones/America/Dawson.ics b/SOPE/NGCards/TimeZones/America/Dawson.ics index e03e0219f..a1586af7f 100644 --- a/SOPE/NGCards/TimeZones/America/Dawson.ics +++ b/SOPE/NGCards/TimeZones/America/Dawson.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Dawson diff --git a/SOPE/NGCards/TimeZones/America/Dawson_Creek.ics b/SOPE/NGCards/TimeZones/America/Dawson_Creek.ics index 329235787..fc82b7c98 100644 --- a/SOPE/NGCards/TimeZones/America/Dawson_Creek.ics +++ b/SOPE/NGCards/TimeZones/America/Dawson_Creek.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Dawson_Creek diff --git a/SOPE/NGCards/TimeZones/America/Denver.ics b/SOPE/NGCards/TimeZones/America/Denver.ics index 59713abad..2997a961d 100644 --- a/SOPE/NGCards/TimeZones/America/Denver.ics +++ b/SOPE/NGCards/TimeZones/America/Denver.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Denver diff --git a/SOPE/NGCards/TimeZones/America/Detroit.ics b/SOPE/NGCards/TimeZones/America/Detroit.ics index 8b0177c31..68ec9beea 100644 --- a/SOPE/NGCards/TimeZones/America/Detroit.ics +++ b/SOPE/NGCards/TimeZones/America/Detroit.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Detroit diff --git a/SOPE/NGCards/TimeZones/America/Dominica.ics b/SOPE/NGCards/TimeZones/America/Dominica.ics index e7f5a4239..9f15f3a4c 100644 --- a/SOPE/NGCards/TimeZones/America/Dominica.ics +++ b/SOPE/NGCards/TimeZones/America/Dominica.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Dominica diff --git a/SOPE/NGCards/TimeZones/America/Edmonton.ics b/SOPE/NGCards/TimeZones/America/Edmonton.ics index 1f40d2fdd..e4ec742ca 100644 --- a/SOPE/NGCards/TimeZones/America/Edmonton.ics +++ b/SOPE/NGCards/TimeZones/America/Edmonton.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Edmonton diff --git a/SOPE/NGCards/TimeZones/America/Eirunepe.ics b/SOPE/NGCards/TimeZones/America/Eirunepe.ics index 9856cf0d5..11b67a599 100644 --- a/SOPE/NGCards/TimeZones/America/Eirunepe.ics +++ b/SOPE/NGCards/TimeZones/America/Eirunepe.ics @@ -1,13 +1,13 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Eirunepe X-LIC-LOCATION:America/Eirunepe BEGIN:STANDARD -TZOFFSETFROM:-0400 -TZOFFSETTO:-0400 -TZNAME:AMT +TZOFFSETFROM:-0500 +TZOFFSETTO:-0500 +TZNAME:ACT DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/America/El_Salvador.ics b/SOPE/NGCards/TimeZones/America/El_Salvador.ics index 0cd1fcc97..f56f0c2ac 100644 --- a/SOPE/NGCards/TimeZones/America/El_Salvador.ics +++ b/SOPE/NGCards/TimeZones/America/El_Salvador.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/El_Salvador diff --git a/SOPE/NGCards/TimeZones/America/Fortaleza.ics b/SOPE/NGCards/TimeZones/America/Fortaleza.ics index 1fd2e54bf..c5d319a74 100644 --- a/SOPE/NGCards/TimeZones/America/Fortaleza.ics +++ b/SOPE/NGCards/TimeZones/America/Fortaleza.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Fortaleza diff --git a/SOPE/NGCards/TimeZones/America/Glace_Bay.ics b/SOPE/NGCards/TimeZones/America/Glace_Bay.ics index 2f6f93eb9..79348fd10 100644 --- a/SOPE/NGCards/TimeZones/America/Glace_Bay.ics +++ b/SOPE/NGCards/TimeZones/America/Glace_Bay.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Glace_Bay diff --git a/SOPE/NGCards/TimeZones/America/Godthab.ics b/SOPE/NGCards/TimeZones/America/Godthab.ics index a8b8e32e9..2a92ffd1e 100644 --- a/SOPE/NGCards/TimeZones/America/Godthab.ics +++ b/SOPE/NGCards/TimeZones/America/Godthab.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Godthab diff --git a/SOPE/NGCards/TimeZones/America/Goose_Bay.ics b/SOPE/NGCards/TimeZones/America/Goose_Bay.ics index f058578c5..7360db74c 100644 --- a/SOPE/NGCards/TimeZones/America/Goose_Bay.ics +++ b/SOPE/NGCards/TimeZones/America/Goose_Bay.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Goose_Bay diff --git a/SOPE/NGCards/TimeZones/America/Grand_Turk.ics b/SOPE/NGCards/TimeZones/America/Grand_Turk.ics index 16307344d..c3a986d75 100644 --- a/SOPE/NGCards/TimeZones/America/Grand_Turk.ics +++ b/SOPE/NGCards/TimeZones/America/Grand_Turk.ics @@ -1,22 +1,14 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Grand_Turk X-LIC-LOCATION:America/Grand_Turk -BEGIN:DAYLIGHT -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -DTSTART:19700308T020000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU -END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -DTSTART:19701101T020000 -RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU +TZOFFSETTO:-0400 +TZNAME:AST +DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/America/Grenada.ics b/SOPE/NGCards/TimeZones/America/Grenada.ics index 0eeb64336..59e7f12b8 100644 --- a/SOPE/NGCards/TimeZones/America/Grenada.ics +++ b/SOPE/NGCards/TimeZones/America/Grenada.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Grenada diff --git a/SOPE/NGCards/TimeZones/America/Guadeloupe.ics b/SOPE/NGCards/TimeZones/America/Guadeloupe.ics index 9408b8c5d..98891c960 100644 --- a/SOPE/NGCards/TimeZones/America/Guadeloupe.ics +++ b/SOPE/NGCards/TimeZones/America/Guadeloupe.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Guadeloupe diff --git a/SOPE/NGCards/TimeZones/America/Guatemala.ics b/SOPE/NGCards/TimeZones/America/Guatemala.ics index 0d330f70e..96b04a78c 100644 --- a/SOPE/NGCards/TimeZones/America/Guatemala.ics +++ b/SOPE/NGCards/TimeZones/America/Guatemala.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Guatemala diff --git a/SOPE/NGCards/TimeZones/America/Guayaquil.ics b/SOPE/NGCards/TimeZones/America/Guayaquil.ics index 60d50cf6b..d293fb044 100644 --- a/SOPE/NGCards/TimeZones/America/Guayaquil.ics +++ b/SOPE/NGCards/TimeZones/America/Guayaquil.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Guayaquil diff --git a/SOPE/NGCards/TimeZones/America/Guyana.ics b/SOPE/NGCards/TimeZones/America/Guyana.ics index 263dbd7d5..fabbccd6d 100644 --- a/SOPE/NGCards/TimeZones/America/Guyana.ics +++ b/SOPE/NGCards/TimeZones/America/Guyana.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Guyana diff --git a/SOPE/NGCards/TimeZones/America/Halifax.ics b/SOPE/NGCards/TimeZones/America/Halifax.ics index 174e87efc..6a05f08da 100644 --- a/SOPE/NGCards/TimeZones/America/Halifax.ics +++ b/SOPE/NGCards/TimeZones/America/Halifax.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Halifax diff --git a/SOPE/NGCards/TimeZones/America/Havana.ics b/SOPE/NGCards/TimeZones/America/Havana.ics index aafe5237b..59fe09946 100644 --- a/SOPE/NGCards/TimeZones/America/Havana.ics +++ b/SOPE/NGCards/TimeZones/America/Havana.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Havana diff --git a/SOPE/NGCards/TimeZones/America/Hermosillo.ics b/SOPE/NGCards/TimeZones/America/Hermosillo.ics index 26045065d..c9e1f9259 100644 --- a/SOPE/NGCards/TimeZones/America/Hermosillo.ics +++ b/SOPE/NGCards/TimeZones/America/Hermosillo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Hermosillo diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Indianapolis.ics b/SOPE/NGCards/TimeZones/America/Indiana/Indianapolis.ics index bb0926256..3c8d99c5c 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Indianapolis.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Indianapolis.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Indianapolis diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Knox.ics b/SOPE/NGCards/TimeZones/America/Indiana/Knox.ics index ff54c8ea0..c80b4ff0b 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Knox.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Knox.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Knox diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Marengo.ics b/SOPE/NGCards/TimeZones/America/Indiana/Marengo.ics index 94d2cfee1..128e7a87f 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Marengo.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Marengo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Marengo diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Petersburg.ics b/SOPE/NGCards/TimeZones/America/Indiana/Petersburg.ics index 16fcc67ab..7d764ac74 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Petersburg.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Petersburg.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Petersburg diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Tell_City.ics b/SOPE/NGCards/TimeZones/America/Indiana/Tell_City.ics index ff0e23bf6..557ddcf6f 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Tell_City.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Tell_City.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Tell_City diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Vevay.ics b/SOPE/NGCards/TimeZones/America/Indiana/Vevay.ics index 8e6c9418e..50440311d 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Vevay.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Vevay.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Vevay diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Vincennes.ics b/SOPE/NGCards/TimeZones/America/Indiana/Vincennes.ics index 065049a31..2552a33dc 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Vincennes.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Vincennes.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Vincennes diff --git a/SOPE/NGCards/TimeZones/America/Indiana/Winamac.ics b/SOPE/NGCards/TimeZones/America/Indiana/Winamac.ics index 60caf1ffe..a9f90e6a0 100644 --- a/SOPE/NGCards/TimeZones/America/Indiana/Winamac.ics +++ b/SOPE/NGCards/TimeZones/America/Indiana/Winamac.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Indiana/Winamac diff --git a/SOPE/NGCards/TimeZones/America/Inuvik.ics b/SOPE/NGCards/TimeZones/America/Inuvik.ics index eecad3d41..66bfa1b5f 100644 --- a/SOPE/NGCards/TimeZones/America/Inuvik.ics +++ b/SOPE/NGCards/TimeZones/America/Inuvik.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Inuvik diff --git a/SOPE/NGCards/TimeZones/America/Iqaluit.ics b/SOPE/NGCards/TimeZones/America/Iqaluit.ics index b30414740..82fa44511 100644 --- a/SOPE/NGCards/TimeZones/America/Iqaluit.ics +++ b/SOPE/NGCards/TimeZones/America/Iqaluit.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Iqaluit diff --git a/SOPE/NGCards/TimeZones/America/Jamaica.ics b/SOPE/NGCards/TimeZones/America/Jamaica.ics index ac8551c59..82b8cc916 100644 --- a/SOPE/NGCards/TimeZones/America/Jamaica.ics +++ b/SOPE/NGCards/TimeZones/America/Jamaica.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Jamaica diff --git a/SOPE/NGCards/TimeZones/America/Juneau.ics b/SOPE/NGCards/TimeZones/America/Juneau.ics index 5f70c8f96..49b06041b 100644 --- a/SOPE/NGCards/TimeZones/America/Juneau.ics +++ b/SOPE/NGCards/TimeZones/America/Juneau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Juneau diff --git a/SOPE/NGCards/TimeZones/America/Kentucky/Louisville.ics b/SOPE/NGCards/TimeZones/America/Kentucky/Louisville.ics index 60dc836cf..276d4bb82 100644 --- a/SOPE/NGCards/TimeZones/America/Kentucky/Louisville.ics +++ b/SOPE/NGCards/TimeZones/America/Kentucky/Louisville.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Kentucky/Louisville diff --git a/SOPE/NGCards/TimeZones/America/Kentucky/Monticello.ics b/SOPE/NGCards/TimeZones/America/Kentucky/Monticello.ics index 9ad8f20a1..441494304 100644 --- a/SOPE/NGCards/TimeZones/America/Kentucky/Monticello.ics +++ b/SOPE/NGCards/TimeZones/America/Kentucky/Monticello.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Kentucky/Monticello diff --git a/SOPE/NGCards/TimeZones/America/Kralendijk.ics b/SOPE/NGCards/TimeZones/America/Kralendijk.ics index 1990a171b..d18d4ed33 100644 --- a/SOPE/NGCards/TimeZones/America/Kralendijk.ics +++ b/SOPE/NGCards/TimeZones/America/Kralendijk.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Kralendijk diff --git a/SOPE/NGCards/TimeZones/America/La_Paz.ics b/SOPE/NGCards/TimeZones/America/La_Paz.ics index aa1f4d470..740e54e8e 100644 --- a/SOPE/NGCards/TimeZones/America/La_Paz.ics +++ b/SOPE/NGCards/TimeZones/America/La_Paz.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/La_Paz diff --git a/SOPE/NGCards/TimeZones/America/Lima.ics b/SOPE/NGCards/TimeZones/America/Lima.ics index 60901a3a0..6760635a7 100644 --- a/SOPE/NGCards/TimeZones/America/Lima.ics +++ b/SOPE/NGCards/TimeZones/America/Lima.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Lima diff --git a/SOPE/NGCards/TimeZones/America/Los_Angeles.ics b/SOPE/NGCards/TimeZones/America/Los_Angeles.ics index dab4d9928..3cd58e02e 100644 --- a/SOPE/NGCards/TimeZones/America/Los_Angeles.ics +++ b/SOPE/NGCards/TimeZones/America/Los_Angeles.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Los_Angeles diff --git a/SOPE/NGCards/TimeZones/America/Lower_Princes.ics b/SOPE/NGCards/TimeZones/America/Lower_Princes.ics index 3600f7918..1b0fed302 100644 --- a/SOPE/NGCards/TimeZones/America/Lower_Princes.ics +++ b/SOPE/NGCards/TimeZones/America/Lower_Princes.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Lower_Princes diff --git a/SOPE/NGCards/TimeZones/America/Maceio.ics b/SOPE/NGCards/TimeZones/America/Maceio.ics index 71ccaced1..8886a31fb 100644 --- a/SOPE/NGCards/TimeZones/America/Maceio.ics +++ b/SOPE/NGCards/TimeZones/America/Maceio.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Maceio diff --git a/SOPE/NGCards/TimeZones/America/Managua.ics b/SOPE/NGCards/TimeZones/America/Managua.ics index 35e074fff..b8b484e09 100644 --- a/SOPE/NGCards/TimeZones/America/Managua.ics +++ b/SOPE/NGCards/TimeZones/America/Managua.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Managua diff --git a/SOPE/NGCards/TimeZones/America/Manaus.ics b/SOPE/NGCards/TimeZones/America/Manaus.ics index 056420b02..a27c9b1c4 100644 --- a/SOPE/NGCards/TimeZones/America/Manaus.ics +++ b/SOPE/NGCards/TimeZones/America/Manaus.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Manaus diff --git a/SOPE/NGCards/TimeZones/America/Marigot.ics b/SOPE/NGCards/TimeZones/America/Marigot.ics index effaf29fd..786c00bf1 100644 --- a/SOPE/NGCards/TimeZones/America/Marigot.ics +++ b/SOPE/NGCards/TimeZones/America/Marigot.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Marigot diff --git a/SOPE/NGCards/TimeZones/America/Martinique.ics b/SOPE/NGCards/TimeZones/America/Martinique.ics index e6824f4c0..d2290f780 100644 --- a/SOPE/NGCards/TimeZones/America/Martinique.ics +++ b/SOPE/NGCards/TimeZones/America/Martinique.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Martinique diff --git a/SOPE/NGCards/TimeZones/America/Matamoros.ics b/SOPE/NGCards/TimeZones/America/Matamoros.ics index 0697f2fb3..fd7175a18 100644 --- a/SOPE/NGCards/TimeZones/America/Matamoros.ics +++ b/SOPE/NGCards/TimeZones/America/Matamoros.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Matamoros diff --git a/SOPE/NGCards/TimeZones/America/Mazatlan.ics b/SOPE/NGCards/TimeZones/America/Mazatlan.ics index 0c6b624c8..6101020b6 100644 --- a/SOPE/NGCards/TimeZones/America/Mazatlan.ics +++ b/SOPE/NGCards/TimeZones/America/Mazatlan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Mazatlan diff --git a/SOPE/NGCards/TimeZones/America/Menominee.ics b/SOPE/NGCards/TimeZones/America/Menominee.ics index 28e7d2aa2..1e0f8c829 100644 --- a/SOPE/NGCards/TimeZones/America/Menominee.ics +++ b/SOPE/NGCards/TimeZones/America/Menominee.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Menominee diff --git a/SOPE/NGCards/TimeZones/America/Merida.ics b/SOPE/NGCards/TimeZones/America/Merida.ics index 8cd04956a..c51e74f12 100644 --- a/SOPE/NGCards/TimeZones/America/Merida.ics +++ b/SOPE/NGCards/TimeZones/America/Merida.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Merida diff --git a/SOPE/NGCards/TimeZones/America/Metlakatla.ics b/SOPE/NGCards/TimeZones/America/Metlakatla.ics index 337e51e45..a01939128 100644 --- a/SOPE/NGCards/TimeZones/America/Metlakatla.ics +++ b/SOPE/NGCards/TimeZones/America/Metlakatla.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Metlakatla @@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Metlakatla BEGIN:STANDARD TZOFFSETFROM:-0800 TZOFFSETTO:-0800 -TZNAME:MeST +TZNAME:PST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/America/Mexico_City.ics b/SOPE/NGCards/TimeZones/America/Mexico_City.ics index df38186de..8ec190747 100644 --- a/SOPE/NGCards/TimeZones/America/Mexico_City.ics +++ b/SOPE/NGCards/TimeZones/America/Mexico_City.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Mexico_City diff --git a/SOPE/NGCards/TimeZones/America/Miquelon.ics b/SOPE/NGCards/TimeZones/America/Miquelon.ics index d80a89732..41f693456 100644 --- a/SOPE/NGCards/TimeZones/America/Miquelon.ics +++ b/SOPE/NGCards/TimeZones/America/Miquelon.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Miquelon diff --git a/SOPE/NGCards/TimeZones/America/Moncton.ics b/SOPE/NGCards/TimeZones/America/Moncton.ics index 8bd77ddd5..dd879d0c4 100644 --- a/SOPE/NGCards/TimeZones/America/Moncton.ics +++ b/SOPE/NGCards/TimeZones/America/Moncton.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Moncton diff --git a/SOPE/NGCards/TimeZones/America/Monterrey.ics b/SOPE/NGCards/TimeZones/America/Monterrey.ics index 214088d9c..122f7f86c 100644 --- a/SOPE/NGCards/TimeZones/America/Monterrey.ics +++ b/SOPE/NGCards/TimeZones/America/Monterrey.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Monterrey diff --git a/SOPE/NGCards/TimeZones/America/Montevideo.ics b/SOPE/NGCards/TimeZones/America/Montevideo.ics index 3a4c37b91..4c40c05ed 100644 --- a/SOPE/NGCards/TimeZones/America/Montevideo.ics +++ b/SOPE/NGCards/TimeZones/America/Montevideo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Montevideo diff --git a/SOPE/NGCards/TimeZones/America/Montreal.ics b/SOPE/NGCards/TimeZones/America/Montreal.ics index 9db0a3437..295e6ecb5 100644 --- a/SOPE/NGCards/TimeZones/America/Montreal.ics +++ b/SOPE/NGCards/TimeZones/America/Montreal.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Montreal diff --git a/SOPE/NGCards/TimeZones/America/Montserrat.ics b/SOPE/NGCards/TimeZones/America/Montserrat.ics index df15bb319..5fa11de22 100644 --- a/SOPE/NGCards/TimeZones/America/Montserrat.ics +++ b/SOPE/NGCards/TimeZones/America/Montserrat.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Montserrat diff --git a/SOPE/NGCards/TimeZones/America/Nassau.ics b/SOPE/NGCards/TimeZones/America/Nassau.ics index 309baa304..42ab8b6a7 100644 --- a/SOPE/NGCards/TimeZones/America/Nassau.ics +++ b/SOPE/NGCards/TimeZones/America/Nassau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Nassau diff --git a/SOPE/NGCards/TimeZones/America/New_York.ics b/SOPE/NGCards/TimeZones/America/New_York.ics index 24e1655f3..d481d1ab5 100644 --- a/SOPE/NGCards/TimeZones/America/New_York.ics +++ b/SOPE/NGCards/TimeZones/America/New_York.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/New_York diff --git a/SOPE/NGCards/TimeZones/America/Nipigon.ics b/SOPE/NGCards/TimeZones/America/Nipigon.ics index 5a093da50..beadac97b 100644 --- a/SOPE/NGCards/TimeZones/America/Nipigon.ics +++ b/SOPE/NGCards/TimeZones/America/Nipigon.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Nipigon diff --git a/SOPE/NGCards/TimeZones/America/Nome.ics b/SOPE/NGCards/TimeZones/America/Nome.ics index b73852a83..1f238457a 100644 --- a/SOPE/NGCards/TimeZones/America/Nome.ics +++ b/SOPE/NGCards/TimeZones/America/Nome.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Nome diff --git a/SOPE/NGCards/TimeZones/America/Noronha.ics b/SOPE/NGCards/TimeZones/America/Noronha.ics index 803d376ac..1b9d4e1d3 100644 --- a/SOPE/NGCards/TimeZones/America/Noronha.ics +++ b/SOPE/NGCards/TimeZones/America/Noronha.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Noronha diff --git a/SOPE/NGCards/TimeZones/America/North_Dakota/Beulah.ics b/SOPE/NGCards/TimeZones/America/North_Dakota/Beulah.ics index 60cfb74bd..07e2a5b43 100644 --- a/SOPE/NGCards/TimeZones/America/North_Dakota/Beulah.ics +++ b/SOPE/NGCards/TimeZones/America/North_Dakota/Beulah.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/North_Dakota/Beulah diff --git a/SOPE/NGCards/TimeZones/America/North_Dakota/Center.ics b/SOPE/NGCards/TimeZones/America/North_Dakota/Center.ics index be2928061..a65e9b433 100644 --- a/SOPE/NGCards/TimeZones/America/North_Dakota/Center.ics +++ b/SOPE/NGCards/TimeZones/America/North_Dakota/Center.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/North_Dakota/Center diff --git a/SOPE/NGCards/TimeZones/America/North_Dakota/New_Salem.ics b/SOPE/NGCards/TimeZones/America/North_Dakota/New_Salem.ics index 73cd7bbe5..1e9a1830b 100644 --- a/SOPE/NGCards/TimeZones/America/North_Dakota/New_Salem.ics +++ b/SOPE/NGCards/TimeZones/America/North_Dakota/New_Salem.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/North_Dakota/New_Salem diff --git a/SOPE/NGCards/TimeZones/America/Ojinaga.ics b/SOPE/NGCards/TimeZones/America/Ojinaga.ics index 55bee6678..f5c05cc28 100644 --- a/SOPE/NGCards/TimeZones/America/Ojinaga.ics +++ b/SOPE/NGCards/TimeZones/America/Ojinaga.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Ojinaga diff --git a/SOPE/NGCards/TimeZones/America/Panama.ics b/SOPE/NGCards/TimeZones/America/Panama.ics index a69835531..b16383a1b 100644 --- a/SOPE/NGCards/TimeZones/America/Panama.ics +++ b/SOPE/NGCards/TimeZones/America/Panama.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Panama diff --git a/SOPE/NGCards/TimeZones/America/Pangnirtung.ics b/SOPE/NGCards/TimeZones/America/Pangnirtung.ics index 7be99b8e4..fbad12d5d 100644 --- a/SOPE/NGCards/TimeZones/America/Pangnirtung.ics +++ b/SOPE/NGCards/TimeZones/America/Pangnirtung.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Pangnirtung diff --git a/SOPE/NGCards/TimeZones/America/Paramaribo.ics b/SOPE/NGCards/TimeZones/America/Paramaribo.ics index 5c2a7fabd..3936d9ded 100644 --- a/SOPE/NGCards/TimeZones/America/Paramaribo.ics +++ b/SOPE/NGCards/TimeZones/America/Paramaribo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Paramaribo diff --git a/SOPE/NGCards/TimeZones/America/Phoenix.ics b/SOPE/NGCards/TimeZones/America/Phoenix.ics index 1aa6a6faa..5782a75f4 100644 --- a/SOPE/NGCards/TimeZones/America/Phoenix.ics +++ b/SOPE/NGCards/TimeZones/America/Phoenix.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Phoenix diff --git a/SOPE/NGCards/TimeZones/America/Port-au-Prince.ics b/SOPE/NGCards/TimeZones/America/Port-au-Prince.ics index 3691bc2cb..98c108e00 100644 --- a/SOPE/NGCards/TimeZones/America/Port-au-Prince.ics +++ b/SOPE/NGCards/TimeZones/America/Port-au-Prince.ics @@ -1,14 +1,22 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Port-au-Prince X-LIC-LOCATION:America/Port-au-Prince -BEGIN:STANDARD +BEGIN:DAYLIGHT TZOFFSETFROM:-0500 +TZOFFSETTO:-0400 +TZNAME:EDT +DTSTART:19700308T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:-0400 TZOFFSETTO:-0500 TZNAME:EST -DTSTART:19700101T000000 +DTSTART:19701101T020000 +RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/America/Port_of_Spain.ics b/SOPE/NGCards/TimeZones/America/Port_of_Spain.ics index 92fc99984..3c292806a 100644 --- a/SOPE/NGCards/TimeZones/America/Port_of_Spain.ics +++ b/SOPE/NGCards/TimeZones/America/Port_of_Spain.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Port_of_Spain diff --git a/SOPE/NGCards/TimeZones/America/Porto_Velho.ics b/SOPE/NGCards/TimeZones/America/Porto_Velho.ics index ae951be97..b1346e61a 100644 --- a/SOPE/NGCards/TimeZones/America/Porto_Velho.ics +++ b/SOPE/NGCards/TimeZones/America/Porto_Velho.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Porto_Velho diff --git a/SOPE/NGCards/TimeZones/America/Puerto_Rico.ics b/SOPE/NGCards/TimeZones/America/Puerto_Rico.ics index 8ac44189a..6173826fa 100644 --- a/SOPE/NGCards/TimeZones/America/Puerto_Rico.ics +++ b/SOPE/NGCards/TimeZones/America/Puerto_Rico.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Puerto_Rico diff --git a/SOPE/NGCards/TimeZones/America/Rainy_River.ics b/SOPE/NGCards/TimeZones/America/Rainy_River.ics index e2b884054..cd03d763c 100644 --- a/SOPE/NGCards/TimeZones/America/Rainy_River.ics +++ b/SOPE/NGCards/TimeZones/America/Rainy_River.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Rainy_River diff --git a/SOPE/NGCards/TimeZones/America/Rankin_Inlet.ics b/SOPE/NGCards/TimeZones/America/Rankin_Inlet.ics index 198d44182..6d010c951 100644 --- a/SOPE/NGCards/TimeZones/America/Rankin_Inlet.ics +++ b/SOPE/NGCards/TimeZones/America/Rankin_Inlet.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Rankin_Inlet diff --git a/SOPE/NGCards/TimeZones/America/Recife.ics b/SOPE/NGCards/TimeZones/America/Recife.ics index 6e2ea9df2..485d87bbe 100644 --- a/SOPE/NGCards/TimeZones/America/Recife.ics +++ b/SOPE/NGCards/TimeZones/America/Recife.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Recife diff --git a/SOPE/NGCards/TimeZones/America/Regina.ics b/SOPE/NGCards/TimeZones/America/Regina.ics index 96460126f..92994ed4c 100644 --- a/SOPE/NGCards/TimeZones/America/Regina.ics +++ b/SOPE/NGCards/TimeZones/America/Regina.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Regina diff --git a/SOPE/NGCards/TimeZones/America/Resolute.ics b/SOPE/NGCards/TimeZones/America/Resolute.ics index d524b185c..00145bb9a 100644 --- a/SOPE/NGCards/TimeZones/America/Resolute.ics +++ b/SOPE/NGCards/TimeZones/America/Resolute.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Resolute diff --git a/SOPE/NGCards/TimeZones/America/Rio_Branco.ics b/SOPE/NGCards/TimeZones/America/Rio_Branco.ics index f638561e0..cddae8895 100644 --- a/SOPE/NGCards/TimeZones/America/Rio_Branco.ics +++ b/SOPE/NGCards/TimeZones/America/Rio_Branco.ics @@ -1,13 +1,13 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Rio_Branco X-LIC-LOCATION:America/Rio_Branco BEGIN:STANDARD -TZOFFSETFROM:-0400 -TZOFFSETTO:-0400 -TZNAME:AMT +TZOFFSETFROM:-0500 +TZOFFSETTO:-0500 +TZNAME:ACT DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/America/Santa_Isabel.ics b/SOPE/NGCards/TimeZones/America/Santa_Isabel.ics index c8e421ab9..1468e443c 100644 --- a/SOPE/NGCards/TimeZones/America/Santa_Isabel.ics +++ b/SOPE/NGCards/TimeZones/America/Santa_Isabel.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Santa_Isabel diff --git a/SOPE/NGCards/TimeZones/America/Santarem.ics b/SOPE/NGCards/TimeZones/America/Santarem.ics index ba8ff63a2..d6d2c1b09 100644 --- a/SOPE/NGCards/TimeZones/America/Santarem.ics +++ b/SOPE/NGCards/TimeZones/America/Santarem.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Santarem diff --git a/SOPE/NGCards/TimeZones/America/Santiago.ics b/SOPE/NGCards/TimeZones/America/Santiago.ics index 8b0acbfd0..68eb0bc9a 100644 --- a/SOPE/NGCards/TimeZones/America/Santiago.ics +++ b/SOPE/NGCards/TimeZones/America/Santiago.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Santiago @@ -8,15 +8,15 @@ BEGIN:STANDARD TZOFFSETFROM:-0300 TZOFFSETTO:-0400 TZNAME:CLT -DTSTART:19700315T000000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU +DTSTART:19700426T000000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:-0400 TZOFFSETTO:-0300 TZNAME:CLST -DTSTART:19701011T000000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=2SU +DTSTART:19700906T000000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=1SU END:DAYLIGHT END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/America/Santo_Domingo.ics b/SOPE/NGCards/TimeZones/America/Santo_Domingo.ics index 349670b6d..0587a50a1 100644 --- a/SOPE/NGCards/TimeZones/America/Santo_Domingo.ics +++ b/SOPE/NGCards/TimeZones/America/Santo_Domingo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Santo_Domingo diff --git a/SOPE/NGCards/TimeZones/America/Sao_Paulo.ics b/SOPE/NGCards/TimeZones/America/Sao_Paulo.ics index 758a423eb..7fc832d3e 100644 --- a/SOPE/NGCards/TimeZones/America/Sao_Paulo.ics +++ b/SOPE/NGCards/TimeZones/America/Sao_Paulo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Sao_Paulo diff --git a/SOPE/NGCards/TimeZones/America/Scoresbysund.ics b/SOPE/NGCards/TimeZones/America/Scoresbysund.ics index 08094020b..4bc9794e3 100644 --- a/SOPE/NGCards/TimeZones/America/Scoresbysund.ics +++ b/SOPE/NGCards/TimeZones/America/Scoresbysund.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Scoresbysund diff --git a/SOPE/NGCards/TimeZones/America/Sitka.ics b/SOPE/NGCards/TimeZones/America/Sitka.ics index 3134ecf82..0ccb73e46 100644 --- a/SOPE/NGCards/TimeZones/America/Sitka.ics +++ b/SOPE/NGCards/TimeZones/America/Sitka.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Sitka diff --git a/SOPE/NGCards/TimeZones/America/St_Barthelemy.ics b/SOPE/NGCards/TimeZones/America/St_Barthelemy.ics index 4e88bf89d..06e9c14d7 100644 --- a/SOPE/NGCards/TimeZones/America/St_Barthelemy.ics +++ b/SOPE/NGCards/TimeZones/America/St_Barthelemy.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/St_Barthelemy diff --git a/SOPE/NGCards/TimeZones/America/St_Johns.ics b/SOPE/NGCards/TimeZones/America/St_Johns.ics index be3d8b134..030fd285e 100644 --- a/SOPE/NGCards/TimeZones/America/St_Johns.ics +++ b/SOPE/NGCards/TimeZones/America/St_Johns.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/St_Johns diff --git a/SOPE/NGCards/TimeZones/America/St_Kitts.ics b/SOPE/NGCards/TimeZones/America/St_Kitts.ics index 20dc45a56..f51516d86 100644 --- a/SOPE/NGCards/TimeZones/America/St_Kitts.ics +++ b/SOPE/NGCards/TimeZones/America/St_Kitts.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/St_Kitts diff --git a/SOPE/NGCards/TimeZones/America/St_Lucia.ics b/SOPE/NGCards/TimeZones/America/St_Lucia.ics index f99308a15..e21f6d2b4 100644 --- a/SOPE/NGCards/TimeZones/America/St_Lucia.ics +++ b/SOPE/NGCards/TimeZones/America/St_Lucia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/St_Lucia diff --git a/SOPE/NGCards/TimeZones/America/St_Thomas.ics b/SOPE/NGCards/TimeZones/America/St_Thomas.ics index ceaf36bd5..8f7537117 100644 --- a/SOPE/NGCards/TimeZones/America/St_Thomas.ics +++ b/SOPE/NGCards/TimeZones/America/St_Thomas.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/St_Thomas diff --git a/SOPE/NGCards/TimeZones/America/St_Vincent.ics b/SOPE/NGCards/TimeZones/America/St_Vincent.ics index 6820a0943..ef4162747 100644 --- a/SOPE/NGCards/TimeZones/America/St_Vincent.ics +++ b/SOPE/NGCards/TimeZones/America/St_Vincent.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/St_Vincent diff --git a/SOPE/NGCards/TimeZones/America/Swift_Current.ics b/SOPE/NGCards/TimeZones/America/Swift_Current.ics index 63a0f4193..494e0de5b 100644 --- a/SOPE/NGCards/TimeZones/America/Swift_Current.ics +++ b/SOPE/NGCards/TimeZones/America/Swift_Current.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Swift_Current diff --git a/SOPE/NGCards/TimeZones/America/Tegucigalpa.ics b/SOPE/NGCards/TimeZones/America/Tegucigalpa.ics index d3e267870..1fa6cdcbb 100644 --- a/SOPE/NGCards/TimeZones/America/Tegucigalpa.ics +++ b/SOPE/NGCards/TimeZones/America/Tegucigalpa.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Tegucigalpa diff --git a/SOPE/NGCards/TimeZones/America/Thule.ics b/SOPE/NGCards/TimeZones/America/Thule.ics index 808440609..b2d49d98c 100644 --- a/SOPE/NGCards/TimeZones/America/Thule.ics +++ b/SOPE/NGCards/TimeZones/America/Thule.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Thule diff --git a/SOPE/NGCards/TimeZones/America/Thunder_Bay.ics b/SOPE/NGCards/TimeZones/America/Thunder_Bay.ics index 9e0bd1458..90464ef84 100644 --- a/SOPE/NGCards/TimeZones/America/Thunder_Bay.ics +++ b/SOPE/NGCards/TimeZones/America/Thunder_Bay.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Thunder_Bay diff --git a/SOPE/NGCards/TimeZones/America/Tijuana.ics b/SOPE/NGCards/TimeZones/America/Tijuana.ics index 04769a097..473e4af9a 100644 --- a/SOPE/NGCards/TimeZones/America/Tijuana.ics +++ b/SOPE/NGCards/TimeZones/America/Tijuana.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Tijuana diff --git a/SOPE/NGCards/TimeZones/America/Toronto.ics b/SOPE/NGCards/TimeZones/America/Toronto.ics index 789aeefdd..c53d26b88 100644 --- a/SOPE/NGCards/TimeZones/America/Toronto.ics +++ b/SOPE/NGCards/TimeZones/America/Toronto.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Toronto diff --git a/SOPE/NGCards/TimeZones/America/Tortola.ics b/SOPE/NGCards/TimeZones/America/Tortola.ics index 999ca9654..c39aa8c85 100644 --- a/SOPE/NGCards/TimeZones/America/Tortola.ics +++ b/SOPE/NGCards/TimeZones/America/Tortola.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Tortola diff --git a/SOPE/NGCards/TimeZones/America/Vancouver.ics b/SOPE/NGCards/TimeZones/America/Vancouver.ics index 0954c1ee9..80eb33716 100644 --- a/SOPE/NGCards/TimeZones/America/Vancouver.ics +++ b/SOPE/NGCards/TimeZones/America/Vancouver.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Vancouver diff --git a/SOPE/NGCards/TimeZones/America/Whitehorse.ics b/SOPE/NGCards/TimeZones/America/Whitehorse.ics index 0774e6106..0f553b0d6 100644 --- a/SOPE/NGCards/TimeZones/America/Whitehorse.ics +++ b/SOPE/NGCards/TimeZones/America/Whitehorse.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Whitehorse diff --git a/SOPE/NGCards/TimeZones/America/Winnipeg.ics b/SOPE/NGCards/TimeZones/America/Winnipeg.ics index 19fa04852..df2ca6e03 100644 --- a/SOPE/NGCards/TimeZones/America/Winnipeg.ics +++ b/SOPE/NGCards/TimeZones/America/Winnipeg.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Winnipeg diff --git a/SOPE/NGCards/TimeZones/America/Yakutat.ics b/SOPE/NGCards/TimeZones/America/Yakutat.ics index 0e9fc4c7b..ba457acca 100644 --- a/SOPE/NGCards/TimeZones/America/Yakutat.ics +++ b/SOPE/NGCards/TimeZones/America/Yakutat.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Yakutat diff --git a/SOPE/NGCards/TimeZones/America/Yellowknife.ics b/SOPE/NGCards/TimeZones/America/Yellowknife.ics index 17d884a7d..390959b93 100644 --- a/SOPE/NGCards/TimeZones/America/Yellowknife.ics +++ b/SOPE/NGCards/TimeZones/America/Yellowknife.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Yellowknife diff --git a/SOPE/NGCards/TimeZones/Antarctica/Casey.ics b/SOPE/NGCards/TimeZones/Antarctica/Casey.ics index a15ec0529..5615ec486 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Casey.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Casey.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Casey @@ -7,7 +7,7 @@ X-LIC-LOCATION:Antarctica/Casey BEGIN:STANDARD TZOFFSETFROM:+0800 TZOFFSETTO:+0800 -TZNAME:WST +TZNAME:AWST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Antarctica/Davis.ics b/SOPE/NGCards/TimeZones/Antarctica/Davis.ics index c7d1ae2d2..27eced8f9 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Davis.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Davis.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Davis diff --git a/SOPE/NGCards/TimeZones/Antarctica/DumontDUrville.ics b/SOPE/NGCards/TimeZones/Antarctica/DumontDUrville.ics index 84c41de6b..3fdc300d2 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/DumontDUrville.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/DumontDUrville.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/DumontDUrville diff --git a/SOPE/NGCards/TimeZones/Antarctica/Macquarie.ics b/SOPE/NGCards/TimeZones/Antarctica/Macquarie.ics index cc7fa92e3..faa991e60 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Macquarie.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Macquarie.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Macquarie diff --git a/SOPE/NGCards/TimeZones/Antarctica/Mawson.ics b/SOPE/NGCards/TimeZones/Antarctica/Mawson.ics index 3daa4ee13..9331d91fd 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Mawson.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Mawson.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Mawson diff --git a/SOPE/NGCards/TimeZones/Antarctica/McMurdo.ics b/SOPE/NGCards/TimeZones/Antarctica/McMurdo.ics index 155b1e10b..9eeee120e 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/McMurdo.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/McMurdo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/McMurdo diff --git a/SOPE/NGCards/TimeZones/Antarctica/Palmer.ics b/SOPE/NGCards/TimeZones/Antarctica/Palmer.ics index d14dce814..1e565d30a 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Palmer.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Palmer.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Palmer @@ -8,15 +8,15 @@ BEGIN:STANDARD TZOFFSETFROM:-0300 TZOFFSETTO:-0400 TZNAME:CLT -DTSTART:19700315T000000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU +DTSTART:19700426T000000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:-0400 TZOFFSETTO:-0300 TZNAME:CLST -DTSTART:19701011T000000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=2SU +DTSTART:19700906T000000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=1SU END:DAYLIGHT END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Antarctica/Rothera.ics b/SOPE/NGCards/TimeZones/Antarctica/Rothera.ics index fb6bdb448..0638f9265 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Rothera.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Rothera.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Rothera diff --git a/SOPE/NGCards/TimeZones/Antarctica/Syowa.ics b/SOPE/NGCards/TimeZones/Antarctica/Syowa.ics index a12a1ce0a..d31a6e5f3 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Syowa.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Syowa.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Syowa diff --git a/SOPE/NGCards/TimeZones/Antarctica/Troll.ics b/SOPE/NGCards/TimeZones/Antarctica/Troll.ics new file mode 100644 index 000000000..e560dec5b --- /dev/null +++ b/SOPE/NGCards/TimeZones/Antarctica/Troll.ics @@ -0,0 +1,22 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Antarctica/Troll +X-LIC-LOCATION:Antarctica/Troll +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0200 +TZNAME:CEST +DTSTART:19700329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0000 +TZNAME:UTC +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Antarctica/Vostok.ics b/SOPE/NGCards/TimeZones/Antarctica/Vostok.ics index cbb1b01a7..ad4637ced 100644 --- a/SOPE/NGCards/TimeZones/Antarctica/Vostok.ics +++ b/SOPE/NGCards/TimeZones/Antarctica/Vostok.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Antarctica/Vostok diff --git a/SOPE/NGCards/TimeZones/Arctic/Longyearbyen.ics b/SOPE/NGCards/TimeZones/Arctic/Longyearbyen.ics index 7616d4a85..6b665b635 100644 --- a/SOPE/NGCards/TimeZones/Arctic/Longyearbyen.ics +++ b/SOPE/NGCards/TimeZones/Arctic/Longyearbyen.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Arctic/Longyearbyen diff --git a/SOPE/NGCards/TimeZones/Asia/Aden.ics b/SOPE/NGCards/TimeZones/Asia/Aden.ics index 9e76f377b..bbcc8c4ce 100644 --- a/SOPE/NGCards/TimeZones/Asia/Aden.ics +++ b/SOPE/NGCards/TimeZones/Asia/Aden.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Aden diff --git a/SOPE/NGCards/TimeZones/Asia/Almaty.ics b/SOPE/NGCards/TimeZones/Asia/Almaty.ics index 00b432ed7..850dd152e 100644 --- a/SOPE/NGCards/TimeZones/Asia/Almaty.ics +++ b/SOPE/NGCards/TimeZones/Asia/Almaty.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Almaty diff --git a/SOPE/NGCards/TimeZones/Asia/Amman.ics b/SOPE/NGCards/TimeZones/Asia/Amman.ics index 1b475278d..d869aa5a4 100644 --- a/SOPE/NGCards/TimeZones/Asia/Amman.ics +++ b/SOPE/NGCards/TimeZones/Asia/Amman.ics @@ -1,16 +1,9 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Amman X-LIC-LOCATION:Asia/Amman -BEGIN:STANDARD -TZOFFSETFROM:+0300 -TZOFFSETTO:+0200 -TZNAME:EET -DTSTART:19701030T010000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1FR -END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0200 TZOFFSETTO:+0300 @@ -18,5 +11,12 @@ TZNAME:EEST DTSTART:19700326T235959 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1TH END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0300 +TZOFFSETTO:+0200 +TZNAME:EET +DTSTART:19701030T010000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1FR +END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Anadyr.ics b/SOPE/NGCards/TimeZones/Asia/Anadyr.ics index 9e2472b42..e7cbc61ff 100644 --- a/SOPE/NGCards/TimeZones/Asia/Anadyr.ics +++ b/SOPE/NGCards/TimeZones/Asia/Anadyr.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Anadyr diff --git a/SOPE/NGCards/TimeZones/Asia/Aqtau.ics b/SOPE/NGCards/TimeZones/Asia/Aqtau.ics index d3fd5bcd5..02a825733 100644 --- a/SOPE/NGCards/TimeZones/Asia/Aqtau.ics +++ b/SOPE/NGCards/TimeZones/Asia/Aqtau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Aqtau diff --git a/SOPE/NGCards/TimeZones/Asia/Aqtobe.ics b/SOPE/NGCards/TimeZones/Asia/Aqtobe.ics index 125fbf8f8..9a49eaf06 100644 --- a/SOPE/NGCards/TimeZones/Asia/Aqtobe.ics +++ b/SOPE/NGCards/TimeZones/Asia/Aqtobe.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Aqtobe diff --git a/SOPE/NGCards/TimeZones/Asia/Ashgabat.ics b/SOPE/NGCards/TimeZones/Asia/Ashgabat.ics index 844cd4762..9f029bc2d 100644 --- a/SOPE/NGCards/TimeZones/Asia/Ashgabat.ics +++ b/SOPE/NGCards/TimeZones/Asia/Ashgabat.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Ashgabat diff --git a/SOPE/NGCards/TimeZones/Asia/Baghdad.ics b/SOPE/NGCards/TimeZones/Asia/Baghdad.ics index 2677e7723..64367d789 100644 --- a/SOPE/NGCards/TimeZones/Asia/Baghdad.ics +++ b/SOPE/NGCards/TimeZones/Asia/Baghdad.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Baghdad diff --git a/SOPE/NGCards/TimeZones/Asia/Bahrain.ics b/SOPE/NGCards/TimeZones/Asia/Bahrain.ics index 141fe7ece..395ca403e 100644 --- a/SOPE/NGCards/TimeZones/Asia/Bahrain.ics +++ b/SOPE/NGCards/TimeZones/Asia/Bahrain.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Bahrain diff --git a/SOPE/NGCards/TimeZones/Asia/Baku.ics b/SOPE/NGCards/TimeZones/Asia/Baku.ics index 50280e026..c0dc191c7 100644 --- a/SOPE/NGCards/TimeZones/Asia/Baku.ics +++ b/SOPE/NGCards/TimeZones/Asia/Baku.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Baku diff --git a/SOPE/NGCards/TimeZones/Asia/Bangkok.ics b/SOPE/NGCards/TimeZones/Asia/Bangkok.ics index 1f002532e..e501819c5 100644 --- a/SOPE/NGCards/TimeZones/Asia/Bangkok.ics +++ b/SOPE/NGCards/TimeZones/Asia/Bangkok.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Bangkok diff --git a/SOPE/NGCards/TimeZones/Asia/Beirut.ics b/SOPE/NGCards/TimeZones/Asia/Beirut.ics index 0629652de..edc258d31 100644 --- a/SOPE/NGCards/TimeZones/Asia/Beirut.ics +++ b/SOPE/NGCards/TimeZones/Asia/Beirut.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Beirut diff --git a/SOPE/NGCards/TimeZones/Asia/Bishkek.ics b/SOPE/NGCards/TimeZones/Asia/Bishkek.ics index a4b212f77..e1da4ed81 100644 --- a/SOPE/NGCards/TimeZones/Asia/Bishkek.ics +++ b/SOPE/NGCards/TimeZones/Asia/Bishkek.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Bishkek diff --git a/SOPE/NGCards/TimeZones/Asia/Brunei.ics b/SOPE/NGCards/TimeZones/Asia/Brunei.ics index 79e886dd2..66ba22436 100644 --- a/SOPE/NGCards/TimeZones/Asia/Brunei.ics +++ b/SOPE/NGCards/TimeZones/Asia/Brunei.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Brunei diff --git a/SOPE/NGCards/TimeZones/Asia/Chita.ics b/SOPE/NGCards/TimeZones/Asia/Chita.ics new file mode 100644 index 000000000..0a2dc2847 --- /dev/null +++ b/SOPE/NGCards/TimeZones/Asia/Chita.ics @@ -0,0 +1,14 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Asia/Chita +X-LIC-LOCATION:Asia/Chita +BEGIN:STANDARD +TZOFFSETFROM:+0800 +TZOFFSETTO:+0800 +TZNAME:IRKT +DTSTART:19700101T000000 +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Choibalsan.ics b/SOPE/NGCards/TimeZones/Asia/Choibalsan.ics index d03a8c603..f14b157ff 100644 --- a/SOPE/NGCards/TimeZones/Asia/Choibalsan.ics +++ b/SOPE/NGCards/TimeZones/Asia/Choibalsan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Choibalsan diff --git a/SOPE/NGCards/TimeZones/Asia/Chongqing.ics b/SOPE/NGCards/TimeZones/Asia/Chongqing.ics index 5ec12f610..10174f2fa 100644 --- a/SOPE/NGCards/TimeZones/Asia/Chongqing.ics +++ b/SOPE/NGCards/TimeZones/Asia/Chongqing.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Chongqing diff --git a/SOPE/NGCards/TimeZones/Asia/Colombo.ics b/SOPE/NGCards/TimeZones/Asia/Colombo.ics index 71bc4f566..73ebaa6d9 100644 --- a/SOPE/NGCards/TimeZones/Asia/Colombo.ics +++ b/SOPE/NGCards/TimeZones/Asia/Colombo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Colombo diff --git a/SOPE/NGCards/TimeZones/Asia/Damascus.ics b/SOPE/NGCards/TimeZones/Asia/Damascus.ics index 5269285e3..fc6ea1f52 100644 --- a/SOPE/NGCards/TimeZones/Asia/Damascus.ics +++ b/SOPE/NGCards/TimeZones/Asia/Damascus.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Damascus diff --git a/SOPE/NGCards/TimeZones/Asia/Dhaka.ics b/SOPE/NGCards/TimeZones/Asia/Dhaka.ics index 035a6a911..57066e539 100644 --- a/SOPE/NGCards/TimeZones/Asia/Dhaka.ics +++ b/SOPE/NGCards/TimeZones/Asia/Dhaka.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Dhaka diff --git a/SOPE/NGCards/TimeZones/Asia/Dili.ics b/SOPE/NGCards/TimeZones/Asia/Dili.ics index 4d2450b9a..1ba76b60e 100644 --- a/SOPE/NGCards/TimeZones/Asia/Dili.ics +++ b/SOPE/NGCards/TimeZones/Asia/Dili.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Dili diff --git a/SOPE/NGCards/TimeZones/Asia/Dubai.ics b/SOPE/NGCards/TimeZones/Asia/Dubai.ics index 0fa8f1667..f71c46ba3 100644 --- a/SOPE/NGCards/TimeZones/Asia/Dubai.ics +++ b/SOPE/NGCards/TimeZones/Asia/Dubai.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Dubai diff --git a/SOPE/NGCards/TimeZones/Asia/Dushanbe.ics b/SOPE/NGCards/TimeZones/Asia/Dushanbe.ics index fcc829d36..cad5fb2cb 100644 --- a/SOPE/NGCards/TimeZones/Asia/Dushanbe.ics +++ b/SOPE/NGCards/TimeZones/Asia/Dushanbe.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Dushanbe diff --git a/SOPE/NGCards/TimeZones/Asia/Gaza.ics b/SOPE/NGCards/TimeZones/Asia/Gaza.ics index 848e37dca..4774d9010 100644 --- a/SOPE/NGCards/TimeZones/Asia/Gaza.ics +++ b/SOPE/NGCards/TimeZones/Asia/Gaza.ics @@ -1,14 +1,22 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Gaza X-LIC-LOCATION:Asia/Gaza -BEGIN:STANDARD +BEGIN:DAYLIGHT TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +TZNAME:EEST +DTSTART:19700326T235959 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1TH +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0300 TZOFFSETTO:+0200 TZNAME:EET -DTSTART:19700101T000000 +DTSTART:19700925T000000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1FR END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Harbin.ics b/SOPE/NGCards/TimeZones/Asia/Harbin.ics index 702f4e8e9..339c58f0d 100644 --- a/SOPE/NGCards/TimeZones/Asia/Harbin.ics +++ b/SOPE/NGCards/TimeZones/Asia/Harbin.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Harbin diff --git a/SOPE/NGCards/TimeZones/Asia/Hebron.ics b/SOPE/NGCards/TimeZones/Asia/Hebron.ics index 4865c4ac6..b7ed636f4 100644 --- a/SOPE/NGCards/TimeZones/Asia/Hebron.ics +++ b/SOPE/NGCards/TimeZones/Asia/Hebron.ics @@ -1,14 +1,22 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Hebron X-LIC-LOCATION:Asia/Hebron -BEGIN:STANDARD +BEGIN:DAYLIGHT TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +TZNAME:EEST +DTSTART:19700326T235959 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1TH +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0300 TZOFFSETTO:+0200 TZNAME:EET -DTSTART:19700101T000000 +DTSTART:19700925T000000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1FR END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Ho_Chi_Minh.ics b/SOPE/NGCards/TimeZones/Asia/Ho_Chi_Minh.ics index 9dc7a02dd..6a6b76734 100644 --- a/SOPE/NGCards/TimeZones/Asia/Ho_Chi_Minh.ics +++ b/SOPE/NGCards/TimeZones/Asia/Ho_Chi_Minh.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Ho_Chi_Minh diff --git a/SOPE/NGCards/TimeZones/Asia/Hong_Kong.ics b/SOPE/NGCards/TimeZones/Asia/Hong_Kong.ics index 69e376e26..370c1c58e 100644 --- a/SOPE/NGCards/TimeZones/Asia/Hong_Kong.ics +++ b/SOPE/NGCards/TimeZones/Asia/Hong_Kong.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Hong_Kong diff --git a/SOPE/NGCards/TimeZones/Asia/Hovd.ics b/SOPE/NGCards/TimeZones/Asia/Hovd.ics index 29cc1be54..4edacf30c 100644 --- a/SOPE/NGCards/TimeZones/Asia/Hovd.ics +++ b/SOPE/NGCards/TimeZones/Asia/Hovd.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Hovd diff --git a/SOPE/NGCards/TimeZones/Asia/Irkutsk.ics b/SOPE/NGCards/TimeZones/Asia/Irkutsk.ics index 22bce1e15..34d6aec6f 100644 --- a/SOPE/NGCards/TimeZones/Asia/Irkutsk.ics +++ b/SOPE/NGCards/TimeZones/Asia/Irkutsk.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Irkutsk X-LIC-LOCATION:Asia/Irkutsk BEGIN:STANDARD -TZOFFSETFROM:+0900 -TZOFFSETTO:+0900 +TZOFFSETFROM:+0800 +TZOFFSETTO:+0800 TZNAME:IRKT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Istanbul.ics b/SOPE/NGCards/TimeZones/Asia/Istanbul.ics index 804de5b1b..101552931 100644 --- a/SOPE/NGCards/TimeZones/Asia/Istanbul.ics +++ b/SOPE/NGCards/TimeZones/Asia/Istanbul.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Istanbul diff --git a/SOPE/NGCards/TimeZones/Asia/Jakarta.ics b/SOPE/NGCards/TimeZones/Asia/Jakarta.ics index 36d91bfaa..1b5c0932a 100644 --- a/SOPE/NGCards/TimeZones/Asia/Jakarta.ics +++ b/SOPE/NGCards/TimeZones/Asia/Jakarta.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Jakarta @@ -7,7 +7,7 @@ X-LIC-LOCATION:Asia/Jakarta BEGIN:STANDARD TZOFFSETFROM:+0700 TZOFFSETTO:+0700 -TZNAME:WIT +TZNAME:WIB DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Asia/Jayapura.ics b/SOPE/NGCards/TimeZones/Asia/Jayapura.ics index da1273060..fbc00784c 100644 --- a/SOPE/NGCards/TimeZones/Asia/Jayapura.ics +++ b/SOPE/NGCards/TimeZones/Asia/Jayapura.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Jayapura @@ -7,7 +7,7 @@ X-LIC-LOCATION:Asia/Jayapura BEGIN:STANDARD TZOFFSETFROM:+0900 TZOFFSETTO:+0900 -TZNAME:EIT +TZNAME:WIT DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Asia/Jerusalem.ics b/SOPE/NGCards/TimeZones/Asia/Jerusalem.ics index 07cd14b37..dcbf988cf 100644 --- a/SOPE/NGCards/TimeZones/Asia/Jerusalem.ics +++ b/SOPE/NGCards/TimeZones/Asia/Jerusalem.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Jerusalem @@ -12,11 +12,11 @@ DTSTART:19700327T020000 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1FR END:DAYLIGHT BEGIN:STANDARD -TZOFFSETFROM:+0200 +TZOFFSETFROM:+0300 TZOFFSETTO:+0200 TZNAME:IST -DTSTART:19701004T020000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU +DTSTART:19701025T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Kabul.ics b/SOPE/NGCards/TimeZones/Asia/Kabul.ics index 782574233..72cd088f9 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kabul.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kabul.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kabul diff --git a/SOPE/NGCards/TimeZones/Asia/Kamchatka.ics b/SOPE/NGCards/TimeZones/Asia/Kamchatka.ics index bb739dfc2..4dff1e192 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kamchatka.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kamchatka.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kamchatka diff --git a/SOPE/NGCards/TimeZones/Asia/Karachi.ics b/SOPE/NGCards/TimeZones/Asia/Karachi.ics index cf453fbd7..e6fb05d55 100644 --- a/SOPE/NGCards/TimeZones/Asia/Karachi.ics +++ b/SOPE/NGCards/TimeZones/Asia/Karachi.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Karachi diff --git a/SOPE/NGCards/TimeZones/Asia/Kashgar.ics b/SOPE/NGCards/TimeZones/Asia/Kashgar.ics index 9bdcb4577..0640cd0c3 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kashgar.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kashgar.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kashgar diff --git a/SOPE/NGCards/TimeZones/Asia/Kathmandu.ics b/SOPE/NGCards/TimeZones/Asia/Kathmandu.ics index c1274a577..63c5df266 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kathmandu.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kathmandu.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kathmandu diff --git a/SOPE/NGCards/TimeZones/Asia/Khandyga.ics b/SOPE/NGCards/TimeZones/Asia/Khandyga.ics new file mode 100644 index 000000000..c6748f928 --- /dev/null +++ b/SOPE/NGCards/TimeZones/Asia/Khandyga.ics @@ -0,0 +1,14 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Asia/Khandyga +X-LIC-LOCATION:Asia/Khandyga +BEGIN:STANDARD +TZOFFSETFROM:+0900 +TZOFFSETTO:+0900 +TZNAME:YAKT +DTSTART:19700101T000000 +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Kolkata.ics b/SOPE/NGCards/TimeZones/Asia/Kolkata.ics index 5cf13334e..b6ba22d3d 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kolkata.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kolkata.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kolkata diff --git a/SOPE/NGCards/TimeZones/Asia/Krasnoyarsk.ics b/SOPE/NGCards/TimeZones/Asia/Krasnoyarsk.ics index 276e43b18..0e6b6866b 100644 --- a/SOPE/NGCards/TimeZones/Asia/Krasnoyarsk.ics +++ b/SOPE/NGCards/TimeZones/Asia/Krasnoyarsk.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Krasnoyarsk X-LIC-LOCATION:Asia/Krasnoyarsk BEGIN:STANDARD -TZOFFSETFROM:+0800 -TZOFFSETTO:+0800 +TZOFFSETFROM:+0700 +TZOFFSETTO:+0700 TZNAME:KRAT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Kuala_Lumpur.ics b/SOPE/NGCards/TimeZones/Asia/Kuala_Lumpur.ics index c4de7b39c..7bf14910d 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kuala_Lumpur.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kuala_Lumpur.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kuala_Lumpur diff --git a/SOPE/NGCards/TimeZones/Asia/Kuching.ics b/SOPE/NGCards/TimeZones/Asia/Kuching.ics index d08a28f64..e1fc44674 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kuching.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kuching.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kuching diff --git a/SOPE/NGCards/TimeZones/Asia/Kuwait.ics b/SOPE/NGCards/TimeZones/Asia/Kuwait.ics index 16a660077..a4d31b96b 100644 --- a/SOPE/NGCards/TimeZones/Asia/Kuwait.ics +++ b/SOPE/NGCards/TimeZones/Asia/Kuwait.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Kuwait diff --git a/SOPE/NGCards/TimeZones/Asia/Macau.ics b/SOPE/NGCards/TimeZones/Asia/Macau.ics index dc7a62967..d437cbe58 100644 --- a/SOPE/NGCards/TimeZones/Asia/Macau.ics +++ b/SOPE/NGCards/TimeZones/Asia/Macau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Macau diff --git a/SOPE/NGCards/TimeZones/Asia/Magadan.ics b/SOPE/NGCards/TimeZones/Asia/Magadan.ics index 9bacf7804..f6f1831fe 100644 --- a/SOPE/NGCards/TimeZones/Asia/Magadan.ics +++ b/SOPE/NGCards/TimeZones/Asia/Magadan.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Magadan X-LIC-LOCATION:Asia/Magadan BEGIN:STANDARD -TZOFFSETFROM:+1200 -TZOFFSETTO:+1200 +TZOFFSETFROM:+1000 +TZOFFSETTO:+1000 TZNAME:MAGT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Makassar.ics b/SOPE/NGCards/TimeZones/Asia/Makassar.ics index 2c0329db6..995f6fbfb 100644 --- a/SOPE/NGCards/TimeZones/Asia/Makassar.ics +++ b/SOPE/NGCards/TimeZones/Asia/Makassar.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Makassar @@ -7,7 +7,7 @@ X-LIC-LOCATION:Asia/Makassar BEGIN:STANDARD TZOFFSETFROM:+0800 TZOFFSETTO:+0800 -TZNAME:CIT +TZNAME:WITA DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Asia/Manila.ics b/SOPE/NGCards/TimeZones/Asia/Manila.ics index ea4fc2c35..1283ed083 100644 --- a/SOPE/NGCards/TimeZones/Asia/Manila.ics +++ b/SOPE/NGCards/TimeZones/Asia/Manila.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Manila diff --git a/SOPE/NGCards/TimeZones/Asia/Muscat.ics b/SOPE/NGCards/TimeZones/Asia/Muscat.ics index 92257be82..103cf8e00 100644 --- a/SOPE/NGCards/TimeZones/Asia/Muscat.ics +++ b/SOPE/NGCards/TimeZones/Asia/Muscat.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Muscat diff --git a/SOPE/NGCards/TimeZones/Asia/Nicosia.ics b/SOPE/NGCards/TimeZones/Asia/Nicosia.ics index 5d7390266..e935fc316 100644 --- a/SOPE/NGCards/TimeZones/Asia/Nicosia.ics +++ b/SOPE/NGCards/TimeZones/Asia/Nicosia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Nicosia diff --git a/SOPE/NGCards/TimeZones/Asia/Novokuznetsk.ics b/SOPE/NGCards/TimeZones/Asia/Novokuznetsk.ics index bd39547ae..44fab38ff 100644 --- a/SOPE/NGCards/TimeZones/Asia/Novokuznetsk.ics +++ b/SOPE/NGCards/TimeZones/Asia/Novokuznetsk.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Novokuznetsk @@ -7,7 +7,7 @@ X-LIC-LOCATION:Asia/Novokuznetsk BEGIN:STANDARD TZOFFSETFROM:+0700 TZOFFSETTO:+0700 -TZNAME:NOVT +TZNAME:KRAT DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Asia/Novosibirsk.ics b/SOPE/NGCards/TimeZones/Asia/Novosibirsk.ics index c6ead1abb..b990bac67 100644 --- a/SOPE/NGCards/TimeZones/Asia/Novosibirsk.ics +++ b/SOPE/NGCards/TimeZones/Asia/Novosibirsk.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Novosibirsk X-LIC-LOCATION:Asia/Novosibirsk BEGIN:STANDARD -TZOFFSETFROM:+0700 -TZOFFSETTO:+0700 +TZOFFSETFROM:+0600 +TZOFFSETTO:+0600 TZNAME:NOVT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Omsk.ics b/SOPE/NGCards/TimeZones/Asia/Omsk.ics index 8f979338f..6b1dc7288 100644 --- a/SOPE/NGCards/TimeZones/Asia/Omsk.ics +++ b/SOPE/NGCards/TimeZones/Asia/Omsk.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Omsk X-LIC-LOCATION:Asia/Omsk BEGIN:STANDARD -TZOFFSETFROM:+0700 -TZOFFSETTO:+0700 +TZOFFSETFROM:+0600 +TZOFFSETTO:+0600 TZNAME:OMST DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Oral.ics b/SOPE/NGCards/TimeZones/Asia/Oral.ics index dd73bf3a2..8966be533 100644 --- a/SOPE/NGCards/TimeZones/Asia/Oral.ics +++ b/SOPE/NGCards/TimeZones/Asia/Oral.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Oral diff --git a/SOPE/NGCards/TimeZones/Asia/Phnom_Penh.ics b/SOPE/NGCards/TimeZones/Asia/Phnom_Penh.ics index 67cb44e24..a555365de 100644 --- a/SOPE/NGCards/TimeZones/Asia/Phnom_Penh.ics +++ b/SOPE/NGCards/TimeZones/Asia/Phnom_Penh.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Phnom_Penh diff --git a/SOPE/NGCards/TimeZones/Asia/Pontianak.ics b/SOPE/NGCards/TimeZones/Asia/Pontianak.ics index 77e0ff294..c81e4f09f 100644 --- a/SOPE/NGCards/TimeZones/Asia/Pontianak.ics +++ b/SOPE/NGCards/TimeZones/Asia/Pontianak.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Pontianak @@ -7,7 +7,7 @@ X-LIC-LOCATION:Asia/Pontianak BEGIN:STANDARD TZOFFSETFROM:+0700 TZOFFSETTO:+0700 -TZNAME:WIT +TZNAME:WIB DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Asia/Pyongyang.ics b/SOPE/NGCards/TimeZones/Asia/Pyongyang.ics index 76f09c97e..891d34b52 100644 --- a/SOPE/NGCards/TimeZones/Asia/Pyongyang.ics +++ b/SOPE/NGCards/TimeZones/Asia/Pyongyang.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Pyongyang diff --git a/SOPE/NGCards/TimeZones/Asia/Qatar.ics b/SOPE/NGCards/TimeZones/Asia/Qatar.ics index 16a258049..73c54bc8c 100644 --- a/SOPE/NGCards/TimeZones/Asia/Qatar.ics +++ b/SOPE/NGCards/TimeZones/Asia/Qatar.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Qatar diff --git a/SOPE/NGCards/TimeZones/Asia/Qyzylorda.ics b/SOPE/NGCards/TimeZones/Asia/Qyzylorda.ics index 5afde0859..b80f4c994 100644 --- a/SOPE/NGCards/TimeZones/Asia/Qyzylorda.ics +++ b/SOPE/NGCards/TimeZones/Asia/Qyzylorda.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Qyzylorda diff --git a/SOPE/NGCards/TimeZones/Asia/Rangoon.ics b/SOPE/NGCards/TimeZones/Asia/Rangoon.ics index 5152279f2..9dfd88f04 100644 --- a/SOPE/NGCards/TimeZones/Asia/Rangoon.ics +++ b/SOPE/NGCards/TimeZones/Asia/Rangoon.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Rangoon diff --git a/SOPE/NGCards/TimeZones/Asia/Riyadh.ics b/SOPE/NGCards/TimeZones/Asia/Riyadh.ics index 065817eea..99e4095e2 100644 --- a/SOPE/NGCards/TimeZones/Asia/Riyadh.ics +++ b/SOPE/NGCards/TimeZones/Asia/Riyadh.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Riyadh diff --git a/SOPE/NGCards/TimeZones/Asia/Sakhalin.ics b/SOPE/NGCards/TimeZones/Asia/Sakhalin.ics index ef0988617..b5a09f49c 100644 --- a/SOPE/NGCards/TimeZones/Asia/Sakhalin.ics +++ b/SOPE/NGCards/TimeZones/Asia/Sakhalin.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Sakhalin X-LIC-LOCATION:Asia/Sakhalin BEGIN:STANDARD -TZOFFSETFROM:+1100 -TZOFFSETTO:+1100 +TZOFFSETFROM:+1000 +TZOFFSETTO:+1000 TZNAME:SAKT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Samarkand.ics b/SOPE/NGCards/TimeZones/Asia/Samarkand.ics index 9d26335d6..98d868047 100644 --- a/SOPE/NGCards/TimeZones/Asia/Samarkand.ics +++ b/SOPE/NGCards/TimeZones/Asia/Samarkand.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Samarkand diff --git a/SOPE/NGCards/TimeZones/Asia/Seoul.ics b/SOPE/NGCards/TimeZones/Asia/Seoul.ics index b6162ab09..639a652b3 100644 --- a/SOPE/NGCards/TimeZones/Asia/Seoul.ics +++ b/SOPE/NGCards/TimeZones/Asia/Seoul.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Seoul diff --git a/SOPE/NGCards/TimeZones/Asia/Shanghai.ics b/SOPE/NGCards/TimeZones/Asia/Shanghai.ics index 5fb8506ca..d3608584f 100644 --- a/SOPE/NGCards/TimeZones/Asia/Shanghai.ics +++ b/SOPE/NGCards/TimeZones/Asia/Shanghai.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Shanghai diff --git a/SOPE/NGCards/TimeZones/Asia/Singapore.ics b/SOPE/NGCards/TimeZones/Asia/Singapore.ics index 11ccf7e42..ad8c12528 100644 --- a/SOPE/NGCards/TimeZones/Asia/Singapore.ics +++ b/SOPE/NGCards/TimeZones/Asia/Singapore.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Singapore diff --git a/SOPE/NGCards/TimeZones/Asia/Srednekolymsk.ics b/SOPE/NGCards/TimeZones/Asia/Srednekolymsk.ics new file mode 100644 index 000000000..923d7119b --- /dev/null +++ b/SOPE/NGCards/TimeZones/Asia/Srednekolymsk.ics @@ -0,0 +1,14 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Asia/Srednekolymsk +X-LIC-LOCATION:Asia/Srednekolymsk +BEGIN:STANDARD +TZOFFSETFROM:+1100 +TZOFFSETTO:+1100 +TZNAME:SRET +DTSTART:19700101T000000 +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Taipei.ics b/SOPE/NGCards/TimeZones/Asia/Taipei.ics index 6b32f8266..0e2da0469 100644 --- a/SOPE/NGCards/TimeZones/Asia/Taipei.ics +++ b/SOPE/NGCards/TimeZones/Asia/Taipei.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Taipei diff --git a/SOPE/NGCards/TimeZones/Asia/Tashkent.ics b/SOPE/NGCards/TimeZones/Asia/Tashkent.ics index d9616b716..a413b5dab 100644 --- a/SOPE/NGCards/TimeZones/Asia/Tashkent.ics +++ b/SOPE/NGCards/TimeZones/Asia/Tashkent.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Tashkent diff --git a/SOPE/NGCards/TimeZones/Asia/Tbilisi.ics b/SOPE/NGCards/TimeZones/Asia/Tbilisi.ics index 529648d01..dc2ce7654 100644 --- a/SOPE/NGCards/TimeZones/Asia/Tbilisi.ics +++ b/SOPE/NGCards/TimeZones/Asia/Tbilisi.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Tbilisi diff --git a/SOPE/NGCards/TimeZones/Asia/Tehran.ics b/SOPE/NGCards/TimeZones/Asia/Tehran.ics index 353382091..5d4fe700f 100644 --- a/SOPE/NGCards/TimeZones/Asia/Tehran.ics +++ b/SOPE/NGCards/TimeZones/Asia/Tehran.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Tehran diff --git a/SOPE/NGCards/TimeZones/Asia/Thimphu.ics b/SOPE/NGCards/TimeZones/Asia/Thimphu.ics index e0fc77b18..a910c1e15 100644 --- a/SOPE/NGCards/TimeZones/Asia/Thimphu.ics +++ b/SOPE/NGCards/TimeZones/Asia/Thimphu.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Thimphu diff --git a/SOPE/NGCards/TimeZones/Asia/Tokyo.ics b/SOPE/NGCards/TimeZones/Asia/Tokyo.ics index 901af164e..9bafe558d 100644 --- a/SOPE/NGCards/TimeZones/Asia/Tokyo.ics +++ b/SOPE/NGCards/TimeZones/Asia/Tokyo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Tokyo diff --git a/SOPE/NGCards/TimeZones/Asia/Ulaanbaatar.ics b/SOPE/NGCards/TimeZones/Asia/Ulaanbaatar.ics index 75ab91a82..7f9841450 100644 --- a/SOPE/NGCards/TimeZones/Asia/Ulaanbaatar.ics +++ b/SOPE/NGCards/TimeZones/Asia/Ulaanbaatar.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Ulaanbaatar diff --git a/SOPE/NGCards/TimeZones/Asia/Urumqi.ics b/SOPE/NGCards/TimeZones/Asia/Urumqi.ics index 659eae551..aac45f973 100644 --- a/SOPE/NGCards/TimeZones/Asia/Urumqi.ics +++ b/SOPE/NGCards/TimeZones/Asia/Urumqi.ics @@ -1,13 +1,13 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Urumqi X-LIC-LOCATION:Asia/Urumqi BEGIN:STANDARD -TZOFFSETFROM:+0800 -TZOFFSETTO:+0800 -TZNAME:CST +TZOFFSETFROM:+0600 +TZOFFSETTO:+0600 +TZNAME:XJT DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Asia/Ust-Nera.ics b/SOPE/NGCards/TimeZones/Asia/Ust-Nera.ics new file mode 100644 index 000000000..f2074d8c5 --- /dev/null +++ b/SOPE/NGCards/TimeZones/Asia/Ust-Nera.ics @@ -0,0 +1,14 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Asia/Ust-Nera +X-LIC-LOCATION:Asia/Ust-Nera +BEGIN:STANDARD +TZOFFSETFROM:+1000 +TZOFFSETTO:+1000 +TZNAME:VLAT +DTSTART:19700101T000000 +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Asia/Vientiane.ics b/SOPE/NGCards/TimeZones/Asia/Vientiane.ics index db6511537..c203d40d3 100644 --- a/SOPE/NGCards/TimeZones/Asia/Vientiane.ics +++ b/SOPE/NGCards/TimeZones/Asia/Vientiane.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Vientiane diff --git a/SOPE/NGCards/TimeZones/Asia/Vladivostok.ics b/SOPE/NGCards/TimeZones/Asia/Vladivostok.ics index d92e88ed8..0a2d901de 100644 --- a/SOPE/NGCards/TimeZones/Asia/Vladivostok.ics +++ b/SOPE/NGCards/TimeZones/Asia/Vladivostok.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Vladivostok X-LIC-LOCATION:Asia/Vladivostok BEGIN:STANDARD -TZOFFSETFROM:+1100 -TZOFFSETTO:+1100 +TZOFFSETFROM:+1000 +TZOFFSETTO:+1000 TZNAME:VLAT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Yakutsk.ics b/SOPE/NGCards/TimeZones/Asia/Yakutsk.ics index 1396c45ff..735464d28 100644 --- a/SOPE/NGCards/TimeZones/Asia/Yakutsk.ics +++ b/SOPE/NGCards/TimeZones/Asia/Yakutsk.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Yakutsk X-LIC-LOCATION:Asia/Yakutsk BEGIN:STANDARD -TZOFFSETFROM:+1000 -TZOFFSETTO:+1000 +TZOFFSETFROM:+0900 +TZOFFSETTO:+0900 TZNAME:YAKT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Yekaterinburg.ics b/SOPE/NGCards/TimeZones/Asia/Yekaterinburg.ics index 8eb26bc5e..5aa0e25ea 100644 --- a/SOPE/NGCards/TimeZones/Asia/Yekaterinburg.ics +++ b/SOPE/NGCards/TimeZones/Asia/Yekaterinburg.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Yekaterinburg X-LIC-LOCATION:Asia/Yekaterinburg BEGIN:STANDARD -TZOFFSETFROM:+0600 -TZOFFSETTO:+0600 +TZOFFSETFROM:+0500 +TZOFFSETTO:+0500 TZNAME:YEKT DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Asia/Yerevan.ics b/SOPE/NGCards/TimeZones/Asia/Yerevan.ics index c9965e090..6cd99027b 100644 --- a/SOPE/NGCards/TimeZones/Asia/Yerevan.ics +++ b/SOPE/NGCards/TimeZones/Asia/Yerevan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Yerevan diff --git a/SOPE/NGCards/TimeZones/Atlantic/Azores.ics b/SOPE/NGCards/TimeZones/Atlantic/Azores.ics index 21b9ab9fb..773a6066a 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Azores.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Azores.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Azores diff --git a/SOPE/NGCards/TimeZones/Atlantic/Bermuda.ics b/SOPE/NGCards/TimeZones/Atlantic/Bermuda.ics index e7bb1e618..5d97b738c 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Bermuda.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Bermuda.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Bermuda diff --git a/SOPE/NGCards/TimeZones/Atlantic/Canary.ics b/SOPE/NGCards/TimeZones/Atlantic/Canary.ics index 4bad5b47d..32a3a98cb 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Canary.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Canary.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Canary diff --git a/SOPE/NGCards/TimeZones/Atlantic/Cape_Verde.ics b/SOPE/NGCards/TimeZones/Atlantic/Cape_Verde.ics index 873e22548..01d628ba5 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Cape_Verde.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Cape_Verde.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Cape_Verde diff --git a/SOPE/NGCards/TimeZones/Atlantic/Faroe.ics b/SOPE/NGCards/TimeZones/Atlantic/Faroe.ics index f4a311925..dabaca66f 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Faroe.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Faroe.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Faroe diff --git a/SOPE/NGCards/TimeZones/Atlantic/Madeira.ics b/SOPE/NGCards/TimeZones/Atlantic/Madeira.ics index a91fa1210..5ee088c5c 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Madeira.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Madeira.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Madeira diff --git a/SOPE/NGCards/TimeZones/Atlantic/Reykjavik.ics b/SOPE/NGCards/TimeZones/Atlantic/Reykjavik.ics index 22933a425..0e559492f 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Reykjavik.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Reykjavik.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Reykjavik diff --git a/SOPE/NGCards/TimeZones/Atlantic/South_Georgia.ics b/SOPE/NGCards/TimeZones/Atlantic/South_Georgia.ics index ea25f37ef..d3722b4ba 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/South_Georgia.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/South_Georgia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/South_Georgia diff --git a/SOPE/NGCards/TimeZones/Atlantic/St_Helena.ics b/SOPE/NGCards/TimeZones/Atlantic/St_Helena.ics index 73f201155..7a68d92f3 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/St_Helena.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/St_Helena.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/St_Helena diff --git a/SOPE/NGCards/TimeZones/Atlantic/Stanley.ics b/SOPE/NGCards/TimeZones/Atlantic/Stanley.ics index fd6963380..51b3953c7 100644 --- a/SOPE/NGCards/TimeZones/Atlantic/Stanley.ics +++ b/SOPE/NGCards/TimeZones/Atlantic/Stanley.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Atlantic/Stanley diff --git a/SOPE/NGCards/TimeZones/Australia/Adelaide.ics b/SOPE/NGCards/TimeZones/Australia/Adelaide.ics index b18150ef1..66b3ac307 100644 --- a/SOPE/NGCards/TimeZones/Australia/Adelaide.ics +++ b/SOPE/NGCards/TimeZones/Australia/Adelaide.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Adelaide @@ -7,14 +7,14 @@ X-LIC-LOCATION:Australia/Adelaide BEGIN:STANDARD TZOFFSETFROM:+1030 TZOFFSETTO:+0930 -TZNAME:CST +TZNAME:ACST DTSTART:19700405T030000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0930 TZOFFSETTO:+1030 -TZNAME:CST +TZNAME:ACDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT diff --git a/SOPE/NGCards/TimeZones/Australia/Brisbane.ics b/SOPE/NGCards/TimeZones/Australia/Brisbane.ics index 41d7d128e..7a45ea91c 100644 --- a/SOPE/NGCards/TimeZones/Australia/Brisbane.ics +++ b/SOPE/NGCards/TimeZones/Australia/Brisbane.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Brisbane @@ -7,7 +7,7 @@ X-LIC-LOCATION:Australia/Brisbane BEGIN:STANDARD TZOFFSETFROM:+1000 TZOFFSETTO:+1000 -TZNAME:EST +TZNAME:AEST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Australia/Broken_Hill.ics b/SOPE/NGCards/TimeZones/Australia/Broken_Hill.ics index 1596260f2..907cc1e5e 100644 --- a/SOPE/NGCards/TimeZones/Australia/Broken_Hill.ics +++ b/SOPE/NGCards/TimeZones/Australia/Broken_Hill.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Broken_Hill @@ -7,14 +7,14 @@ X-LIC-LOCATION:Australia/Broken_Hill BEGIN:STANDARD TZOFFSETFROM:+1030 TZOFFSETTO:+0930 -TZNAME:CST +TZNAME:ACST DTSTART:19700405T030000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0930 TZOFFSETTO:+1030 -TZNAME:CST +TZNAME:ACDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT diff --git a/SOPE/NGCards/TimeZones/Australia/Currie.ics b/SOPE/NGCards/TimeZones/Australia/Currie.ics index bf8ebfdb3..ef930e5b9 100644 --- a/SOPE/NGCards/TimeZones/Australia/Currie.ics +++ b/SOPE/NGCards/TimeZones/Australia/Currie.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Currie @@ -7,14 +7,14 @@ X-LIC-LOCATION:Australia/Currie BEGIN:DAYLIGHT TZOFFSETFROM:+1000 TZOFFSETTO:+1100 -TZNAME:EST +TZNAME:AEDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+1100 TZOFFSETTO:+1000 -TZNAME:EST +TZNAME:AEST DTSTART:19700405T030000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Australia/Darwin.ics b/SOPE/NGCards/TimeZones/Australia/Darwin.ics index 1adf7de3d..7fa76ef0b 100644 --- a/SOPE/NGCards/TimeZones/Australia/Darwin.ics +++ b/SOPE/NGCards/TimeZones/Australia/Darwin.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Darwin @@ -7,7 +7,7 @@ X-LIC-LOCATION:Australia/Darwin BEGIN:STANDARD TZOFFSETFROM:+0930 TZOFFSETTO:+0930 -TZNAME:CST +TZNAME:ACST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Australia/Eucla.ics b/SOPE/NGCards/TimeZones/Australia/Eucla.ics index 557d522d4..6005ce50b 100644 --- a/SOPE/NGCards/TimeZones/Australia/Eucla.ics +++ b/SOPE/NGCards/TimeZones/Australia/Eucla.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Eucla @@ -7,7 +7,7 @@ X-LIC-LOCATION:Australia/Eucla BEGIN:STANDARD TZOFFSETFROM:+0845 TZOFFSETTO:+0845 -TZNAME:CWST +TZNAME:ACWST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Australia/Hobart.ics b/SOPE/NGCards/TimeZones/Australia/Hobart.ics index 87636b62f..978063408 100644 --- a/SOPE/NGCards/TimeZones/Australia/Hobart.ics +++ b/SOPE/NGCards/TimeZones/Australia/Hobart.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Hobart @@ -7,14 +7,14 @@ X-LIC-LOCATION:Australia/Hobart BEGIN:DAYLIGHT TZOFFSETFROM:+1000 TZOFFSETTO:+1100 -TZNAME:EST +TZNAME:AEDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+1100 TZOFFSETTO:+1000 -TZNAME:EST +TZNAME:AEST DTSTART:19700405T030000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Australia/Lindeman.ics b/SOPE/NGCards/TimeZones/Australia/Lindeman.ics index eebac0d60..cfe9cdf50 100644 --- a/SOPE/NGCards/TimeZones/Australia/Lindeman.ics +++ b/SOPE/NGCards/TimeZones/Australia/Lindeman.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Lindeman @@ -7,7 +7,7 @@ X-LIC-LOCATION:Australia/Lindeman BEGIN:STANDARD TZOFFSETFROM:+1000 TZOFFSETTO:+1000 -TZNAME:EST +TZNAME:AEST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Australia/Lord_Howe.ics b/SOPE/NGCards/TimeZones/Australia/Lord_Howe.ics index e3d6fc1d6..3340d9e96 100644 --- a/SOPE/NGCards/TimeZones/Australia/Lord_Howe.ics +++ b/SOPE/NGCards/TimeZones/Australia/Lord_Howe.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Lord_Howe @@ -14,7 +14,7 @@ END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+1030 TZOFFSETTO:+1100 -TZNAME:LHST +TZNAME:LHDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT diff --git a/SOPE/NGCards/TimeZones/Australia/Melbourne.ics b/SOPE/NGCards/TimeZones/Australia/Melbourne.ics index 289ac67a6..a7bb35647 100644 --- a/SOPE/NGCards/TimeZones/Australia/Melbourne.ics +++ b/SOPE/NGCards/TimeZones/Australia/Melbourne.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Melbourne @@ -7,14 +7,14 @@ X-LIC-LOCATION:Australia/Melbourne BEGIN:STANDARD TZOFFSETFROM:+1100 TZOFFSETTO:+1000 -TZNAME:EST +TZNAME:AEST DTSTART:19700405T030000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+1000 TZOFFSETTO:+1100 -TZNAME:EST +TZNAME:AEDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT diff --git a/SOPE/NGCards/TimeZones/Australia/Perth.ics b/SOPE/NGCards/TimeZones/Australia/Perth.ics index 5a8ae1b33..ec00a350c 100644 --- a/SOPE/NGCards/TimeZones/Australia/Perth.ics +++ b/SOPE/NGCards/TimeZones/Australia/Perth.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Perth @@ -7,7 +7,7 @@ X-LIC-LOCATION:Australia/Perth BEGIN:STANDARD TZOFFSETFROM:+0800 TZOFFSETTO:+0800 -TZNAME:WST +TZNAME:AWST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Australia/Sydney.ics b/SOPE/NGCards/TimeZones/Australia/Sydney.ics index 636dc54c1..0a0642f03 100644 --- a/SOPE/NGCards/TimeZones/Australia/Sydney.ics +++ b/SOPE/NGCards/TimeZones/Australia/Sydney.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Australia/Sydney @@ -7,14 +7,14 @@ X-LIC-LOCATION:Australia/Sydney BEGIN:STANDARD TZOFFSETFROM:+1100 TZOFFSETTO:+1000 -TZNAME:EST +TZNAME:AEST DTSTART:19700405T030000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+1000 TZOFFSETTO:+1100 -TZNAME:EST +TZNAME:AEDT DTSTART:19701004T020000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU END:DAYLIGHT diff --git a/SOPE/NGCards/TimeZones/Europe/Amsterdam.ics b/SOPE/NGCards/TimeZones/Europe/Amsterdam.ics index 9a38a036b..c468d8849 100644 --- a/SOPE/NGCards/TimeZones/Europe/Amsterdam.ics +++ b/SOPE/NGCards/TimeZones/Europe/Amsterdam.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Amsterdam diff --git a/SOPE/NGCards/TimeZones/Europe/Andorra.ics b/SOPE/NGCards/TimeZones/Europe/Andorra.ics index 310d7f10d..b446891e2 100644 --- a/SOPE/NGCards/TimeZones/Europe/Andorra.ics +++ b/SOPE/NGCards/TimeZones/Europe/Andorra.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Andorra diff --git a/SOPE/NGCards/TimeZones/Europe/Athens.ics b/SOPE/NGCards/TimeZones/Europe/Athens.ics index 99fe600e4..8f8950747 100644 --- a/SOPE/NGCards/TimeZones/Europe/Athens.ics +++ b/SOPE/NGCards/TimeZones/Europe/Athens.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Athens diff --git a/SOPE/NGCards/TimeZones/Europe/Belgrade.ics b/SOPE/NGCards/TimeZones/Europe/Belgrade.ics index b74f4b374..ecdf3d673 100644 --- a/SOPE/NGCards/TimeZones/Europe/Belgrade.ics +++ b/SOPE/NGCards/TimeZones/Europe/Belgrade.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Belgrade diff --git a/SOPE/NGCards/TimeZones/Europe/Berlin.ics b/SOPE/NGCards/TimeZones/Europe/Berlin.ics index 8da1441c8..51eb7c836 100644 --- a/SOPE/NGCards/TimeZones/Europe/Berlin.ics +++ b/SOPE/NGCards/TimeZones/Europe/Berlin.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Berlin diff --git a/SOPE/NGCards/TimeZones/Europe/Bratislava.ics b/SOPE/NGCards/TimeZones/Europe/Bratislava.ics index 36367fe1d..cde22cd0c 100644 --- a/SOPE/NGCards/TimeZones/Europe/Bratislava.ics +++ b/SOPE/NGCards/TimeZones/Europe/Bratislava.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Bratislava diff --git a/SOPE/NGCards/TimeZones/Europe/Brussels.ics b/SOPE/NGCards/TimeZones/Europe/Brussels.ics index d8a7ad167..034580c65 100644 --- a/SOPE/NGCards/TimeZones/Europe/Brussels.ics +++ b/SOPE/NGCards/TimeZones/Europe/Brussels.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Brussels diff --git a/SOPE/NGCards/TimeZones/Europe/Bucharest.ics b/SOPE/NGCards/TimeZones/Europe/Bucharest.ics index eab94c225..66b13bd17 100644 --- a/SOPE/NGCards/TimeZones/Europe/Bucharest.ics +++ b/SOPE/NGCards/TimeZones/Europe/Bucharest.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Bucharest diff --git a/SOPE/NGCards/TimeZones/Europe/Budapest.ics b/SOPE/NGCards/TimeZones/Europe/Budapest.ics index d17453032..41d932e30 100644 --- a/SOPE/NGCards/TimeZones/Europe/Budapest.ics +++ b/SOPE/NGCards/TimeZones/Europe/Budapest.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Budapest diff --git a/SOPE/NGCards/TimeZones/Europe/Busingen.ics b/SOPE/NGCards/TimeZones/Europe/Busingen.ics new file mode 100644 index 000000000..f95294d59 --- /dev/null +++ b/SOPE/NGCards/TimeZones/Europe/Busingen.ics @@ -0,0 +1,22 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/Busingen +X-LIC-LOCATION:Europe/Busingen +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:CEST +DTSTART:19700329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:CET +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Europe/Chisinau.ics b/SOPE/NGCards/TimeZones/Europe/Chisinau.ics index 314ee030d..c9da246f5 100644 --- a/SOPE/NGCards/TimeZones/Europe/Chisinau.ics +++ b/SOPE/NGCards/TimeZones/Europe/Chisinau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Chisinau diff --git a/SOPE/NGCards/TimeZones/Europe/Copenhagen.ics b/SOPE/NGCards/TimeZones/Europe/Copenhagen.ics index 74c948781..bfb4640a4 100644 --- a/SOPE/NGCards/TimeZones/Europe/Copenhagen.ics +++ b/SOPE/NGCards/TimeZones/Europe/Copenhagen.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Copenhagen diff --git a/SOPE/NGCards/TimeZones/Europe/Dublin.ics b/SOPE/NGCards/TimeZones/Europe/Dublin.ics index cef88f036..d092758e5 100644 --- a/SOPE/NGCards/TimeZones/Europe/Dublin.ics +++ b/SOPE/NGCards/TimeZones/Europe/Dublin.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Dublin diff --git a/SOPE/NGCards/TimeZones/Europe/Gibraltar.ics b/SOPE/NGCards/TimeZones/Europe/Gibraltar.ics index 004937430..3f250f1dc 100644 --- a/SOPE/NGCards/TimeZones/Europe/Gibraltar.ics +++ b/SOPE/NGCards/TimeZones/Europe/Gibraltar.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Gibraltar diff --git a/SOPE/NGCards/TimeZones/Europe/Guernsey.ics b/SOPE/NGCards/TimeZones/Europe/Guernsey.ics index f0aa154d6..38c31ffe6 100644 --- a/SOPE/NGCards/TimeZones/Europe/Guernsey.ics +++ b/SOPE/NGCards/TimeZones/Europe/Guernsey.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Guernsey diff --git a/SOPE/NGCards/TimeZones/Europe/Helsinki.ics b/SOPE/NGCards/TimeZones/Europe/Helsinki.ics index 9fcf261de..0f1c42aaf 100644 --- a/SOPE/NGCards/TimeZones/Europe/Helsinki.ics +++ b/SOPE/NGCards/TimeZones/Europe/Helsinki.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Helsinki diff --git a/SOPE/NGCards/TimeZones/Europe/Isle_of_Man.ics b/SOPE/NGCards/TimeZones/Europe/Isle_of_Man.ics index abc5f4e7d..85e670b14 100644 --- a/SOPE/NGCards/TimeZones/Europe/Isle_of_Man.ics +++ b/SOPE/NGCards/TimeZones/Europe/Isle_of_Man.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Isle_of_Man diff --git a/SOPE/NGCards/TimeZones/Europe/Istanbul.ics b/SOPE/NGCards/TimeZones/Europe/Istanbul.ics index 1b0870509..a7642f5fb 100644 --- a/SOPE/NGCards/TimeZones/Europe/Istanbul.ics +++ b/SOPE/NGCards/TimeZones/Europe/Istanbul.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Istanbul diff --git a/SOPE/NGCards/TimeZones/Europe/Jersey.ics b/SOPE/NGCards/TimeZones/Europe/Jersey.ics index d4d8d9aed..a009202f9 100644 --- a/SOPE/NGCards/TimeZones/Europe/Jersey.ics +++ b/SOPE/NGCards/TimeZones/Europe/Jersey.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Jersey diff --git a/SOPE/NGCards/TimeZones/Europe/Kaliningrad.ics b/SOPE/NGCards/TimeZones/Europe/Kaliningrad.ics index fb43f6611..366fe4a5a 100644 --- a/SOPE/NGCards/TimeZones/Europe/Kaliningrad.ics +++ b/SOPE/NGCards/TimeZones/Europe/Kaliningrad.ics @@ -1,13 +1,13 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Kaliningrad X-LIC-LOCATION:Europe/Kaliningrad BEGIN:STANDARD -TZOFFSETFROM:+0300 -TZOFFSETTO:+0300 -TZNAME:FET +TZOFFSETFROM:+0200 +TZOFFSETTO:+0200 +TZNAME:EET DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Europe/Kiev.ics b/SOPE/NGCards/TimeZones/Europe/Kiev.ics index 1e2eb04c4..1c0abd3ae 100644 --- a/SOPE/NGCards/TimeZones/Europe/Kiev.ics +++ b/SOPE/NGCards/TimeZones/Europe/Kiev.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Kiev diff --git a/SOPE/NGCards/TimeZones/Europe/Lisbon.ics b/SOPE/NGCards/TimeZones/Europe/Lisbon.ics index af75a9757..91f6d448a 100644 --- a/SOPE/NGCards/TimeZones/Europe/Lisbon.ics +++ b/SOPE/NGCards/TimeZones/Europe/Lisbon.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Lisbon diff --git a/SOPE/NGCards/TimeZones/Europe/Ljubljana.ics b/SOPE/NGCards/TimeZones/Europe/Ljubljana.ics index 983520411..f4976327d 100644 --- a/SOPE/NGCards/TimeZones/Europe/Ljubljana.ics +++ b/SOPE/NGCards/TimeZones/Europe/Ljubljana.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Ljubljana diff --git a/SOPE/NGCards/TimeZones/Europe/London.ics b/SOPE/NGCards/TimeZones/Europe/London.ics index f95dea6eb..7927a158c 100644 --- a/SOPE/NGCards/TimeZones/Europe/London.ics +++ b/SOPE/NGCards/TimeZones/Europe/London.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/London diff --git a/SOPE/NGCards/TimeZones/Europe/Luxembourg.ics b/SOPE/NGCards/TimeZones/Europe/Luxembourg.ics index 90b8b9593..5fc71f540 100644 --- a/SOPE/NGCards/TimeZones/Europe/Luxembourg.ics +++ b/SOPE/NGCards/TimeZones/Europe/Luxembourg.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Luxembourg diff --git a/SOPE/NGCards/TimeZones/Europe/Madrid.ics b/SOPE/NGCards/TimeZones/Europe/Madrid.ics index 0ad3e4f05..3ee66e256 100644 --- a/SOPE/NGCards/TimeZones/Europe/Madrid.ics +++ b/SOPE/NGCards/TimeZones/Europe/Madrid.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Madrid diff --git a/SOPE/NGCards/TimeZones/Europe/Malta.ics b/SOPE/NGCards/TimeZones/Europe/Malta.ics index 88e52df2f..c7c56589a 100644 --- a/SOPE/NGCards/TimeZones/Europe/Malta.ics +++ b/SOPE/NGCards/TimeZones/Europe/Malta.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Malta diff --git a/SOPE/NGCards/TimeZones/Europe/Mariehamn.ics b/SOPE/NGCards/TimeZones/Europe/Mariehamn.ics index f51889b79..44f3ffa8f 100644 --- a/SOPE/NGCards/TimeZones/Europe/Mariehamn.ics +++ b/SOPE/NGCards/TimeZones/Europe/Mariehamn.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Mariehamn diff --git a/SOPE/NGCards/TimeZones/Europe/Minsk.ics b/SOPE/NGCards/TimeZones/Europe/Minsk.ics index 06eee1b1e..b33e610ee 100644 --- a/SOPE/NGCards/TimeZones/Europe/Minsk.ics +++ b/SOPE/NGCards/TimeZones/Europe/Minsk.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Minsk @@ -7,7 +7,7 @@ X-LIC-LOCATION:Europe/Minsk BEGIN:STANDARD TZOFFSETFROM:+0300 TZOFFSETTO:+0300 -TZNAME:FET +TZNAME:MSK DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Europe/Monaco.ics b/SOPE/NGCards/TimeZones/Europe/Monaco.ics index 307e8f812..2862287c1 100644 --- a/SOPE/NGCards/TimeZones/Europe/Monaco.ics +++ b/SOPE/NGCards/TimeZones/Europe/Monaco.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Monaco diff --git a/SOPE/NGCards/TimeZones/Europe/Moscow.ics b/SOPE/NGCards/TimeZones/Europe/Moscow.ics index a90dea87b..f0e62dbc5 100644 --- a/SOPE/NGCards/TimeZones/Europe/Moscow.ics +++ b/SOPE/NGCards/TimeZones/Europe/Moscow.ics @@ -1,12 +1,12 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Moscow X-LIC-LOCATION:Europe/Moscow BEGIN:STANDARD -TZOFFSETFROM:+0400 -TZOFFSETTO:+0400 +TZOFFSETFROM:+0300 +TZOFFSETTO:+0300 TZNAME:MSK DTSTART:19700101T000000 END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Europe/Nicosia.ics b/SOPE/NGCards/TimeZones/Europe/Nicosia.ics index c4b107b4b..53d126c94 100644 --- a/SOPE/NGCards/TimeZones/Europe/Nicosia.ics +++ b/SOPE/NGCards/TimeZones/Europe/Nicosia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Nicosia diff --git a/SOPE/NGCards/TimeZones/Europe/Oslo.ics b/SOPE/NGCards/TimeZones/Europe/Oslo.ics index 984df709a..98a06d9c6 100644 --- a/SOPE/NGCards/TimeZones/Europe/Oslo.ics +++ b/SOPE/NGCards/TimeZones/Europe/Oslo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Oslo diff --git a/SOPE/NGCards/TimeZones/Europe/Paris.ics b/SOPE/NGCards/TimeZones/Europe/Paris.ics index 1cf338d2f..fb3ab55cc 100644 --- a/SOPE/NGCards/TimeZones/Europe/Paris.ics +++ b/SOPE/NGCards/TimeZones/Europe/Paris.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Paris diff --git a/SOPE/NGCards/TimeZones/Europe/Podgorica.ics b/SOPE/NGCards/TimeZones/Europe/Podgorica.ics index 9c4e90ac8..9d00f19d5 100644 --- a/SOPE/NGCards/TimeZones/Europe/Podgorica.ics +++ b/SOPE/NGCards/TimeZones/Europe/Podgorica.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Podgorica diff --git a/SOPE/NGCards/TimeZones/Europe/Prague.ics b/SOPE/NGCards/TimeZones/Europe/Prague.ics index 42171d5c2..0d937be30 100644 --- a/SOPE/NGCards/TimeZones/Europe/Prague.ics +++ b/SOPE/NGCards/TimeZones/Europe/Prague.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Prague diff --git a/SOPE/NGCards/TimeZones/Europe/Riga.ics b/SOPE/NGCards/TimeZones/Europe/Riga.ics index d47d3c7fd..8a8832a54 100644 --- a/SOPE/NGCards/TimeZones/Europe/Riga.ics +++ b/SOPE/NGCards/TimeZones/Europe/Riga.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Riga diff --git a/SOPE/NGCards/TimeZones/Europe/Rome.ics b/SOPE/NGCards/TimeZones/Europe/Rome.ics index f4d52060d..2c782178b 100644 --- a/SOPE/NGCards/TimeZones/Europe/Rome.ics +++ b/SOPE/NGCards/TimeZones/Europe/Rome.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Rome diff --git a/SOPE/NGCards/TimeZones/Europe/Samara.ics b/SOPE/NGCards/TimeZones/Europe/Samara.ics index c195879af..986aee23b 100644 --- a/SOPE/NGCards/TimeZones/Europe/Samara.ics +++ b/SOPE/NGCards/TimeZones/Europe/Samara.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Samara diff --git a/SOPE/NGCards/TimeZones/Europe/San_Marino.ics b/SOPE/NGCards/TimeZones/Europe/San_Marino.ics index 3618bea41..4454142bd 100644 --- a/SOPE/NGCards/TimeZones/Europe/San_Marino.ics +++ b/SOPE/NGCards/TimeZones/Europe/San_Marino.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/San_Marino diff --git a/SOPE/NGCards/TimeZones/Europe/Sarajevo.ics b/SOPE/NGCards/TimeZones/Europe/Sarajevo.ics index 5396845fc..69920c271 100644 --- a/SOPE/NGCards/TimeZones/Europe/Sarajevo.ics +++ b/SOPE/NGCards/TimeZones/Europe/Sarajevo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Sarajevo diff --git a/SOPE/NGCards/TimeZones/Europe/Simferopol.ics b/SOPE/NGCards/TimeZones/Europe/Simferopol.ics index 2480f4f12..68d857fc4 100644 --- a/SOPE/NGCards/TimeZones/Europe/Simferopol.ics +++ b/SOPE/NGCards/TimeZones/Europe/Simferopol.ics @@ -1,22 +1,14 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Simferopol X-LIC-LOCATION:Europe/Simferopol BEGIN:STANDARD TZOFFSETFROM:+0300 -TZOFFSETTO:+0200 -TZNAME:EET -DTSTART:19701025T040000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU -END:STANDARD -BEGIN:DAYLIGHT -TZOFFSETFROM:+0200 TZOFFSETTO:+0300 -TZNAME:EEST -DTSTART:19700329T030000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU -END:DAYLIGHT +TZNAME:MSK +DTSTART:19700101T000000 +END:STANDARD END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Europe/Skopje.ics b/SOPE/NGCards/TimeZones/Europe/Skopje.ics index 2bb8d2eed..3cf4a4f3b 100644 --- a/SOPE/NGCards/TimeZones/Europe/Skopje.ics +++ b/SOPE/NGCards/TimeZones/Europe/Skopje.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Skopje diff --git a/SOPE/NGCards/TimeZones/Europe/Sofia.ics b/SOPE/NGCards/TimeZones/Europe/Sofia.ics index b4c2ffb54..b91c00f7d 100644 --- a/SOPE/NGCards/TimeZones/Europe/Sofia.ics +++ b/SOPE/NGCards/TimeZones/Europe/Sofia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Sofia diff --git a/SOPE/NGCards/TimeZones/Europe/Stockholm.ics b/SOPE/NGCards/TimeZones/Europe/Stockholm.ics index 38e92dd9f..ae003f724 100644 --- a/SOPE/NGCards/TimeZones/Europe/Stockholm.ics +++ b/SOPE/NGCards/TimeZones/Europe/Stockholm.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Stockholm diff --git a/SOPE/NGCards/TimeZones/Europe/Tallinn.ics b/SOPE/NGCards/TimeZones/Europe/Tallinn.ics index 94cbacce4..804511728 100644 --- a/SOPE/NGCards/TimeZones/Europe/Tallinn.ics +++ b/SOPE/NGCards/TimeZones/Europe/Tallinn.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Tallinn diff --git a/SOPE/NGCards/TimeZones/Europe/Tirane.ics b/SOPE/NGCards/TimeZones/Europe/Tirane.ics index 26b413331..f4a2140b4 100644 --- a/SOPE/NGCards/TimeZones/Europe/Tirane.ics +++ b/SOPE/NGCards/TimeZones/Europe/Tirane.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Tirane diff --git a/SOPE/NGCards/TimeZones/Europe/Uzhgorod.ics b/SOPE/NGCards/TimeZones/Europe/Uzhgorod.ics index ab6f52ef5..0257039ec 100644 --- a/SOPE/NGCards/TimeZones/Europe/Uzhgorod.ics +++ b/SOPE/NGCards/TimeZones/Europe/Uzhgorod.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Uzhgorod diff --git a/SOPE/NGCards/TimeZones/Europe/Vaduz.ics b/SOPE/NGCards/TimeZones/Europe/Vaduz.ics index c7ccf697d..48653e682 100644 --- a/SOPE/NGCards/TimeZones/Europe/Vaduz.ics +++ b/SOPE/NGCards/TimeZones/Europe/Vaduz.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Vaduz diff --git a/SOPE/NGCards/TimeZones/Europe/Vatican.ics b/SOPE/NGCards/TimeZones/Europe/Vatican.ics index a9e0c6123..84e07243b 100644 --- a/SOPE/NGCards/TimeZones/Europe/Vatican.ics +++ b/SOPE/NGCards/TimeZones/Europe/Vatican.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Vatican diff --git a/SOPE/NGCards/TimeZones/Europe/Vienna.ics b/SOPE/NGCards/TimeZones/Europe/Vienna.ics index eb9834d8f..6852c3e81 100644 --- a/SOPE/NGCards/TimeZones/Europe/Vienna.ics +++ b/SOPE/NGCards/TimeZones/Europe/Vienna.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Vienna diff --git a/SOPE/NGCards/TimeZones/Europe/Vilnius.ics b/SOPE/NGCards/TimeZones/Europe/Vilnius.ics index 313e7d86a..365303f11 100644 --- a/SOPE/NGCards/TimeZones/Europe/Vilnius.ics +++ b/SOPE/NGCards/TimeZones/Europe/Vilnius.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Vilnius diff --git a/SOPE/NGCards/TimeZones/Europe/Volgograd.ics b/SOPE/NGCards/TimeZones/Europe/Volgograd.ics index 8718cc5d6..64490487a 100644 --- a/SOPE/NGCards/TimeZones/Europe/Volgograd.ics +++ b/SOPE/NGCards/TimeZones/Europe/Volgograd.ics @@ -1,13 +1,13 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Volgograd X-LIC-LOCATION:Europe/Volgograd BEGIN:STANDARD -TZOFFSETFROM:+0400 -TZOFFSETTO:+0400 -TZNAME:VOLT +TZOFFSETFROM:+0300 +TZOFFSETTO:+0300 +TZNAME:MSK DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE diff --git a/SOPE/NGCards/TimeZones/Europe/Warsaw.ics b/SOPE/NGCards/TimeZones/Europe/Warsaw.ics index 6f9c7ab46..879258a5b 100644 --- a/SOPE/NGCards/TimeZones/Europe/Warsaw.ics +++ b/SOPE/NGCards/TimeZones/Europe/Warsaw.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Warsaw diff --git a/SOPE/NGCards/TimeZones/Europe/Zagreb.ics b/SOPE/NGCards/TimeZones/Europe/Zagreb.ics index 316b08ba1..0f0a56e85 100644 --- a/SOPE/NGCards/TimeZones/Europe/Zagreb.ics +++ b/SOPE/NGCards/TimeZones/Europe/Zagreb.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Zagreb diff --git a/SOPE/NGCards/TimeZones/Europe/Zaporozhye.ics b/SOPE/NGCards/TimeZones/Europe/Zaporozhye.ics index cc8a04b6d..f0d7746ee 100644 --- a/SOPE/NGCards/TimeZones/Europe/Zaporozhye.ics +++ b/SOPE/NGCards/TimeZones/Europe/Zaporozhye.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Zaporozhye diff --git a/SOPE/NGCards/TimeZones/Europe/Zurich.ics b/SOPE/NGCards/TimeZones/Europe/Zurich.ics index 82d6b02ff..44ae49e75 100644 --- a/SOPE/NGCards/TimeZones/Europe/Zurich.ics +++ b/SOPE/NGCards/TimeZones/Europe/Zurich.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Zurich diff --git a/SOPE/NGCards/TimeZones/Indian/Antananarivo.ics b/SOPE/NGCards/TimeZones/Indian/Antananarivo.ics index 8c8bd4c33..3549d11ec 100644 --- a/SOPE/NGCards/TimeZones/Indian/Antananarivo.ics +++ b/SOPE/NGCards/TimeZones/Indian/Antananarivo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Antananarivo diff --git a/SOPE/NGCards/TimeZones/Indian/Chagos.ics b/SOPE/NGCards/TimeZones/Indian/Chagos.ics index a702621bc..8b137f28f 100644 --- a/SOPE/NGCards/TimeZones/Indian/Chagos.ics +++ b/SOPE/NGCards/TimeZones/Indian/Chagos.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Chagos diff --git a/SOPE/NGCards/TimeZones/Indian/Christmas.ics b/SOPE/NGCards/TimeZones/Indian/Christmas.ics index da05a5258..bd46774a5 100644 --- a/SOPE/NGCards/TimeZones/Indian/Christmas.ics +++ b/SOPE/NGCards/TimeZones/Indian/Christmas.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Christmas diff --git a/SOPE/NGCards/TimeZones/Indian/Cocos.ics b/SOPE/NGCards/TimeZones/Indian/Cocos.ics index 0182fd350..553323e87 100644 --- a/SOPE/NGCards/TimeZones/Indian/Cocos.ics +++ b/SOPE/NGCards/TimeZones/Indian/Cocos.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Cocos diff --git a/SOPE/NGCards/TimeZones/Indian/Comoro.ics b/SOPE/NGCards/TimeZones/Indian/Comoro.ics index fe0fe7429..867bca442 100644 --- a/SOPE/NGCards/TimeZones/Indian/Comoro.ics +++ b/SOPE/NGCards/TimeZones/Indian/Comoro.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Comoro diff --git a/SOPE/NGCards/TimeZones/Indian/Kerguelen.ics b/SOPE/NGCards/TimeZones/Indian/Kerguelen.ics index 770d4bc48..55aa7516e 100644 --- a/SOPE/NGCards/TimeZones/Indian/Kerguelen.ics +++ b/SOPE/NGCards/TimeZones/Indian/Kerguelen.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Kerguelen diff --git a/SOPE/NGCards/TimeZones/Indian/Mahe.ics b/SOPE/NGCards/TimeZones/Indian/Mahe.ics index 3fcdd199e..dbbe8976b 100644 --- a/SOPE/NGCards/TimeZones/Indian/Mahe.ics +++ b/SOPE/NGCards/TimeZones/Indian/Mahe.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Mahe diff --git a/SOPE/NGCards/TimeZones/Indian/Maldives.ics b/SOPE/NGCards/TimeZones/Indian/Maldives.ics index ad81069d3..e3f755414 100644 --- a/SOPE/NGCards/TimeZones/Indian/Maldives.ics +++ b/SOPE/NGCards/TimeZones/Indian/Maldives.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Maldives diff --git a/SOPE/NGCards/TimeZones/Indian/Mauritius.ics b/SOPE/NGCards/TimeZones/Indian/Mauritius.ics index a109de782..835717da7 100644 --- a/SOPE/NGCards/TimeZones/Indian/Mauritius.ics +++ b/SOPE/NGCards/TimeZones/Indian/Mauritius.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Mauritius diff --git a/SOPE/NGCards/TimeZones/Indian/Mayotte.ics b/SOPE/NGCards/TimeZones/Indian/Mayotte.ics index 63f714303..bde743401 100644 --- a/SOPE/NGCards/TimeZones/Indian/Mayotte.ics +++ b/SOPE/NGCards/TimeZones/Indian/Mayotte.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Mayotte diff --git a/SOPE/NGCards/TimeZones/Indian/Reunion.ics b/SOPE/NGCards/TimeZones/Indian/Reunion.ics index 306f8f3de..ae4c185b7 100644 --- a/SOPE/NGCards/TimeZones/Indian/Reunion.ics +++ b/SOPE/NGCards/TimeZones/Indian/Reunion.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Indian/Reunion diff --git a/SOPE/NGCards/TimeZones/Pacific/Apia.ics b/SOPE/NGCards/TimeZones/Pacific/Apia.ics index 6b5560239..9b1853a34 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Apia.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Apia.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Apia @@ -7,7 +7,7 @@ X-LIC-LOCATION:Pacific/Apia BEGIN:STANDARD TZOFFSETFROM:+1400 TZOFFSETTO:+1300 -TZNAME:WST +TZNAME:WSST DTSTART:19700405T040000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU END:STANDARD diff --git a/SOPE/NGCards/TimeZones/Pacific/Auckland.ics b/SOPE/NGCards/TimeZones/Pacific/Auckland.ics index fc67f9868..3f8b6eca9 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Auckland.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Auckland.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Auckland diff --git a/SOPE/NGCards/TimeZones/Pacific/Bougainville.ics b/SOPE/NGCards/TimeZones/Pacific/Bougainville.ics new file mode 100644 index 000000000..2b97b3bd2 --- /dev/null +++ b/SOPE/NGCards/TimeZones/Pacific/Bougainville.ics @@ -0,0 +1,14 @@ +BEGIN:VCALENDAR +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Pacific/Bougainville +X-LIC-LOCATION:Pacific/Bougainville +BEGIN:STANDARD +TZOFFSETFROM:+1100 +TZOFFSETTO:+1100 +TZNAME:BST +DTSTART:19700101T000000 +END:STANDARD +END:VTIMEZONE +END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Pacific/Chatham.ics b/SOPE/NGCards/TimeZones/Pacific/Chatham.ics index 7025715a7..4e75651f2 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Chatham.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Chatham.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Chatham diff --git a/SOPE/NGCards/TimeZones/Pacific/Chuuk.ics b/SOPE/NGCards/TimeZones/Pacific/Chuuk.ics index 4412052d6..1ae8cd371 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Chuuk.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Chuuk.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Chuuk diff --git a/SOPE/NGCards/TimeZones/Pacific/Easter.ics b/SOPE/NGCards/TimeZones/Pacific/Easter.ics index 82c622fec..17df2232c 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Easter.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Easter.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Easter @@ -8,15 +8,15 @@ BEGIN:STANDARD TZOFFSETFROM:-0500 TZOFFSETTO:-0600 TZNAME:EAST -DTSTART:19700314T220000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SA +DTSTART:19700425T220000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=4SA END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:-0600 TZOFFSETTO:-0500 TZNAME:EASST -DTSTART:19701010T220000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=2SA +DTSTART:19700905T220000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=1SA END:DAYLIGHT END:VTIMEZONE END:VCALENDAR diff --git a/SOPE/NGCards/TimeZones/Pacific/Efate.ics b/SOPE/NGCards/TimeZones/Pacific/Efate.ics index b81aaf7a9..d75d14c6c 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Efate.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Efate.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Efate diff --git a/SOPE/NGCards/TimeZones/Pacific/Enderbury.ics b/SOPE/NGCards/TimeZones/Pacific/Enderbury.ics index ea38ccf20..2a87dd0e8 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Enderbury.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Enderbury.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Enderbury diff --git a/SOPE/NGCards/TimeZones/Pacific/Fakaofo.ics b/SOPE/NGCards/TimeZones/Pacific/Fakaofo.ics index d655879f4..53e4ca6fe 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Fakaofo.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Fakaofo.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Fakaofo diff --git a/SOPE/NGCards/TimeZones/Pacific/Fiji.ics b/SOPE/NGCards/TimeZones/Pacific/Fiji.ics index c38d96763..224450303 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Fiji.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Fiji.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Fiji @@ -8,8 +8,8 @@ BEGIN:DAYLIGHT TZOFFSETFROM:+1200 TZOFFSETTO:+1300 TZNAME:FJST -DTSTART:19701018T020000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +DTSTART:19701101T020000 +RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+1300 diff --git a/SOPE/NGCards/TimeZones/Pacific/Funafuti.ics b/SOPE/NGCards/TimeZones/Pacific/Funafuti.ics index b0ae3f620..973850a9c 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Funafuti.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Funafuti.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Funafuti diff --git a/SOPE/NGCards/TimeZones/Pacific/Galapagos.ics b/SOPE/NGCards/TimeZones/Pacific/Galapagos.ics index deb928773..eca405da5 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Galapagos.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Galapagos.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Galapagos diff --git a/SOPE/NGCards/TimeZones/Pacific/Gambier.ics b/SOPE/NGCards/TimeZones/Pacific/Gambier.ics index 4c6f1bf45..3e5c08aef 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Gambier.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Gambier.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Gambier diff --git a/SOPE/NGCards/TimeZones/Pacific/Guadalcanal.ics b/SOPE/NGCards/TimeZones/Pacific/Guadalcanal.ics index e9328d410..ec474a766 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Guadalcanal.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Guadalcanal.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Guadalcanal diff --git a/SOPE/NGCards/TimeZones/Pacific/Guam.ics b/SOPE/NGCards/TimeZones/Pacific/Guam.ics index 74b9a134d..109a53abb 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Guam.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Guam.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Guam diff --git a/SOPE/NGCards/TimeZones/Pacific/Honolulu.ics b/SOPE/NGCards/TimeZones/Pacific/Honolulu.ics index 3e3079804..3a2c729e8 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Honolulu.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Honolulu.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Honolulu diff --git a/SOPE/NGCards/TimeZones/Pacific/Johnston.ics b/SOPE/NGCards/TimeZones/Pacific/Johnston.ics index 6e658946e..2f1b3d66e 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Johnston.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Johnston.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Johnston diff --git a/SOPE/NGCards/TimeZones/Pacific/Kiritimati.ics b/SOPE/NGCards/TimeZones/Pacific/Kiritimati.ics index be6338aba..cdbf23939 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Kiritimati.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Kiritimati.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Kiritimati diff --git a/SOPE/NGCards/TimeZones/Pacific/Kosrae.ics b/SOPE/NGCards/TimeZones/Pacific/Kosrae.ics index 48e924058..8e763d826 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Kosrae.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Kosrae.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Kosrae diff --git a/SOPE/NGCards/TimeZones/Pacific/Kwajalein.ics b/SOPE/NGCards/TimeZones/Pacific/Kwajalein.ics index 1b0a700bc..33f479337 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Kwajalein.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Kwajalein.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Kwajalein diff --git a/SOPE/NGCards/TimeZones/Pacific/Majuro.ics b/SOPE/NGCards/TimeZones/Pacific/Majuro.ics index ec61f9043..bbc050402 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Majuro.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Majuro.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Majuro diff --git a/SOPE/NGCards/TimeZones/Pacific/Marquesas.ics b/SOPE/NGCards/TimeZones/Pacific/Marquesas.ics index 1b6e90549..09c32491b 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Marquesas.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Marquesas.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Marquesas diff --git a/SOPE/NGCards/TimeZones/Pacific/Midway.ics b/SOPE/NGCards/TimeZones/Pacific/Midway.ics index 1e7526cc6..3a0114f2a 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Midway.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Midway.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Midway diff --git a/SOPE/NGCards/TimeZones/Pacific/Nauru.ics b/SOPE/NGCards/TimeZones/Pacific/Nauru.ics index 2e5aaceab..f95f1bdae 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Nauru.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Nauru.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Nauru diff --git a/SOPE/NGCards/TimeZones/Pacific/Niue.ics b/SOPE/NGCards/TimeZones/Pacific/Niue.ics index e54772e00..809002904 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Niue.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Niue.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Niue diff --git a/SOPE/NGCards/TimeZones/Pacific/Norfolk.ics b/SOPE/NGCards/TimeZones/Pacific/Norfolk.ics index 0e4ab1c0f..bf29b647e 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Norfolk.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Norfolk.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Norfolk diff --git a/SOPE/NGCards/TimeZones/Pacific/Noumea.ics b/SOPE/NGCards/TimeZones/Pacific/Noumea.ics index a843996e4..b2993c61d 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Noumea.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Noumea.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Noumea diff --git a/SOPE/NGCards/TimeZones/Pacific/Pago_Pago.ics b/SOPE/NGCards/TimeZones/Pacific/Pago_Pago.ics index a8422a1e0..8b0cdcd2d 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Pago_Pago.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Pago_Pago.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Pago_Pago diff --git a/SOPE/NGCards/TimeZones/Pacific/Palau.ics b/SOPE/NGCards/TimeZones/Pacific/Palau.ics index d20da0487..fedb561b8 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Palau.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Palau.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Palau diff --git a/SOPE/NGCards/TimeZones/Pacific/Pitcairn.ics b/SOPE/NGCards/TimeZones/Pacific/Pitcairn.ics index 3cd8ae58f..6715340a0 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Pitcairn.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Pitcairn.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Pitcairn diff --git a/SOPE/NGCards/TimeZones/Pacific/Pohnpei.ics b/SOPE/NGCards/TimeZones/Pacific/Pohnpei.ics index 171078c1b..dea718b8b 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Pohnpei.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Pohnpei.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Pohnpei diff --git a/SOPE/NGCards/TimeZones/Pacific/Port_Moresby.ics b/SOPE/NGCards/TimeZones/Pacific/Port_Moresby.ics index 7c6bd5ab3..77adeae18 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Port_Moresby.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Port_Moresby.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Port_Moresby diff --git a/SOPE/NGCards/TimeZones/Pacific/Rarotonga.ics b/SOPE/NGCards/TimeZones/Pacific/Rarotonga.ics index 5d338ace2..67150a539 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Rarotonga.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Rarotonga.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Rarotonga diff --git a/SOPE/NGCards/TimeZones/Pacific/Saipan.ics b/SOPE/NGCards/TimeZones/Pacific/Saipan.ics index 9e2657025..d807627d0 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Saipan.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Saipan.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Saipan diff --git a/SOPE/NGCards/TimeZones/Pacific/Tahiti.ics b/SOPE/NGCards/TimeZones/Pacific/Tahiti.ics index 49f65f443..47a0a65a2 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Tahiti.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Tahiti.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Tahiti diff --git a/SOPE/NGCards/TimeZones/Pacific/Tarawa.ics b/SOPE/NGCards/TimeZones/Pacific/Tarawa.ics index 95ec5c0ba..891bf4473 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Tarawa.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Tarawa.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Tarawa diff --git a/SOPE/NGCards/TimeZones/Pacific/Tongatapu.ics b/SOPE/NGCards/TimeZones/Pacific/Tongatapu.ics index f76bd985b..f1b447586 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Tongatapu.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Tongatapu.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Tongatapu diff --git a/SOPE/NGCards/TimeZones/Pacific/Wake.ics b/SOPE/NGCards/TimeZones/Pacific/Wake.ics index 3b1440224..21cc1f0c9 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Wake.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Wake.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Wake diff --git a/SOPE/NGCards/TimeZones/Pacific/Wallis.ics b/SOPE/NGCards/TimeZones/Pacific/Wallis.ics index 39005411b..7823e2d40 100644 --- a/SOPE/NGCards/TimeZones/Pacific/Wallis.ics +++ b/SOPE/NGCards/TimeZones/Pacific/Wallis.ics @@ -1,5 +1,5 @@ BEGIN:VCALENDAR -PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN +PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Pacific/Wallis diff --git a/SOPE/NGCards/TimeZones/UPDATING b/SOPE/NGCards/TimeZones/UPDATING index ad8e4b6cd..d8a436434 100644 --- a/SOPE/NGCards/TimeZones/UPDATING +++ b/SOPE/NGCards/TimeZones/UPDATING @@ -7,8 +7,8 @@ To updated the timezone files: mkdir /tmp/zones cd /tmp/zones - wget ftp://munnari.oz.au/pub/oldtz/tzdata2012j.tar.gz - tar -zxvf tzdata2012j.tar.gz + wget http://www.iana.org/time-zones/repository/releases/tzdata2014i.tar.gz + tar -zxvf tzdata2014i.tar.gz 3- run the conversion tool diff --git a/SOPE/NGCards/iCalObject.m b/SOPE/NGCards/iCalObject.m index af13798b1..485bd8be6 100644 --- a/SOPE/NGCards/iCalObject.m +++ b/SOPE/NGCards/iCalObject.m @@ -59,8 +59,8 @@ static NSTimeZone *defTZ = nil; [self takeValue:_value forXKey:_key]; } else { - NSLog(@"0x%08x[%@]: ignoring attempt to set unbound key '%@'", - self, NSStringFromClass([self class]), _key); + //NSLog(@"0x%08x[%@]: ignoring attempt to set unbound key '%@'", + // self, NSStringFromClass([self class]), _key); } } diff --git a/SOPE/NGCards/iCalTimeZonePeriod.m b/SOPE/NGCards/iCalTimeZonePeriod.m index 5da8db47a..1326b329f 100644 --- a/SOPE/NGCards/iCalTimeZonePeriod.m +++ b/SOPE/NGCards/iCalTimeZonePeriod.m @@ -156,13 +156,15 @@ [tzStart setTimeZone: [NSTimeZone timeZoneWithName: @"GMT"]]; tmpDate = [NSCalendarDate dateWithYear: [refDate yearOfCommonEra] month: [[[rrule byMonth] objectAtIndex: 0] intValue] - day: 1 hour: [tzStart hourOfDay] + day: 1 + hour: [tzStart hourOfDay] minute: [tzStart minuteOfHour] second: 0 timeZone: [NSTimeZone timeZoneWithName: @"GMT"]]; + tmpDate = [tmpDate addYear: 0 month: ((pos > 0) ? 0 : 1) day: 0 hour: 0 minute: 0 second: 0]; - + /* If the day of the time change is "-XSU", we need to determine whether the first day of next month is in the same week. In practice, as most time changes occurs on sundays, it will be false only when that first day is a @@ -171,10 +173,42 @@ if (dateDayOfWeek > dayOfWeek && pos < 0) pos++; + /* We check if the days of the week are identical. This is important because if they + are, "pos" actually includes the first day of tmpDate which means we must decrement + pos by 1. This happens for example in the eastern timezone (America/Montreal) + in 2015. We have: + + BEGIN:VTIMEZONE + TZID:America/Montreal + X-LIC-LOCATION:America/Montreal + BEGIN:DAYLIGHT + TZOFFSETFROM:-0500 + TZOFFSETTO:-0400 + TZNAME:EDT + DTSTART:19700308T020000 + RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU + END:DAYLIGHT + BEGIN:STANDARD + TZOFFSETFROM:-0400 + TZOFFSETTO:-0500 + TZNAME:EST + DTSTART:19701101T020000 + RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU + END:STANDARD + END:VTIMEZONE + + The time changes occure on a Sunday, but in March, the 1st is a Sunday itself and in November + the 1st is also a Sunday. If we don't decrement "pos" by one, tmpDate (which is set to March or November 1st + because of "day: 1" will have 14 more days added for March and 7 more days added for November - which will + effectively shift the time change by a whole week. + */ + if (dayOfWeek == dateDayOfWeek) + pos--; + offset = (dayOfWeek - dateDayOfWeek) + (pos * 7); tmpDate = [tmpDate addYear: 0 month: 0 day: offset hour: 0 minute: 0 second: 0]; - + return tmpDate; } diff --git a/SoObjects/Appointments/BrazilianPortuguese.lproj/Localizable.strings b/SoObjects/Appointments/BrazilianPortuguese.lproj/Localizable.strings index c9dcbb802..f6117f8ef 100644 --- a/SoObjects/Appointments/BrazilianPortuguese.lproj/Localizable.strings +++ b/SoObjects/Appointments/BrazilianPortuguese.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"Inviting the following persons is prohibited:" = "Convidando as seguintes pessoas é proibido:"; "Personal Calendar" = "Calendário Pessoal"; vevent_class0 = "(Evento Público)"; vevent_class1 = "(Evento Privado)"; diff --git a/SoObjects/Appointments/GNUmakefile b/SoObjects/Appointments/GNUmakefile index 5d0a40152..55c66a1bd 100644 --- a/SoObjects/Appointments/GNUmakefile +++ b/SoObjects/Appointments/GNUmakefile @@ -9,6 +9,7 @@ Appointments_PRINCIPAL_CLASS = SOGoAppointmentsProduct Appointments_OBJC_FILES = \ Product.m \ NSArray+Appointments.m \ + iCalAlarm+SOGo.m \ iCalCalendar+SOGo.m \ iCalEntityObject+SOGo.m \ iCalRepeatableEntityObject+SOGo.m \ diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 0b5399107..fc1552235 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -487,16 +487,47 @@ static Class iCalEventK = nil; inCategory: @"FolderSynchronize"]; } +// +// If the user is the owner of the calendar, by default we include the freebusy information. +// +// If the user is NOT the owner of the calendar, by default we exclude the freebusy information. +// +// We must include the freebusy information of other users if we are actually looking at their freebusy information +// but we aren't necessarily subscribed to their calendars. +// - (BOOL) includeInFreeBusy { NSNumber *excludeFromFreeBusy; - + NSString *userLogin; + BOOL is_owner; + + userLogin = [[context activeUser] login]; + is_owner = [userLogin isEqualToString: [self ownerInContext: context]]; + // Check if the owner (not the active user) has excluded the calendar from her/his free busy data. excludeFromFreeBusy = [self folderPropertyValueInCategory: @"FreeBusyExclusions" - forUser: [SOGoUser userWithLogin: [self ownerInContext: context]]]; + forUser: [SOGoUser userWithLogin: userLogin]]; - return ![excludeFromFreeBusy boolValue]; + if ([self isSubscription]) + { + // If the user has not yet set an include/not include fb information let's EXCLUDE it. + if (!excludeFromFreeBusy) + return NO; + else + return ![excludeFromFreeBusy boolValue]; + } + else if (is_owner) + { + // We are the owner but we haven't included/excluded freebusy info, let's INCLUDE it. + if (!excludeFromFreeBusy) + return YES; + else + return ![excludeFromFreeBusy boolValue]; + } + + // It's not a subscribtion and we aren't the owner. Let's INCLUDE the freebusy info. + return YES; } - (void) setIncludeInFreeBusy: (BOOL) newInclude @@ -895,11 +926,6 @@ static Class iCalEventK = nil; dateSecs = [NSNumber numberWithInt: [date timeIntervalSince1970]]; [record setObject: dateSecs forKey: @"c_enddate"]; - // The first instance date is added to the dictionary so it can - // be used by UIxCalListingActions to compute the DST offset. - date = [theFirstCycle startDate]; - [record setObject: date forKey: @"cycleStartDate"]; - return record; } @@ -1072,9 +1098,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir [newRecord setObject: dateSecs forKey: @"c_recurrence_id"]; [newRecord setObject: [NSNumber numberWithInt: 1] forKey: @"c_iscycle"]; - // The first instance date is added to the dictionary so it can - // be used by UIxCalListingActions to compute the DST offset. - [newRecord setObject: [fir startDate] forKey: @"cycleStartDate"]; + // We identified the record as an exception. [newRecord setObject: [NSNumber numberWithInt: 1] forKey: @"isException"]; @@ -2818,8 +2842,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir return nil; } - sql = [NSString stringWithFormat: @"((c_nextalarm <= %u) AND (c_nextalarm >= %u)) OR ((c_nextalarm > 0) AND (c_enddate > %u))", - [_endUTCDate unsignedIntValue], [_startUTCDate unsignedIntValue], [_startUTCDate unsignedIntValue]]; + sql = [NSString stringWithFormat: @"((c_nextalarm <= %u) AND (c_nextalarm >= %u)) OR ((c_nextalarm > 0) AND (c_nextalarm <= %u) AND (c_enddate > %u))", + [_endUTCDate unsignedIntValue], [_startUTCDate unsignedIntValue], [_startUTCDate unsignedIntValue], [_startUTCDate unsignedIntValue]]; qualifier = [EOQualifier qualifierWithQualifierFormat: sql]; records = [folder fetchFields: nameFields matchingQualifier: qualifier]; diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.m b/SoObjects/Appointments/SOGoAppointmentFolders.m index 10361c006..2b8ee88c7 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolders.m +++ b/SoObjects/Appointments/SOGoAppointmentFolders.m @@ -1,7 +1,7 @@ /* SOGoAppointmentFolders.m - this file is part of SOGo * - * Copyright (C) 2007-2014 Inverse inc. + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/Appointments/SOGoAppointmentObject.h b/SoObjects/Appointments/SOGoAppointmentObject.h index 6abfb6c0d..8ab78d0a0 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.h +++ b/SoObjects/Appointments/SOGoAppointmentObject.h @@ -30,6 +30,7 @@ @class WORequest; +@class iCalAlarm; @class iCalEvent; @class iCalCalendar; @@ -38,9 +39,12 @@ @interface SOGoAppointmentObject : SOGoCalendarComponent - (NSException *) changeParticipationStatus: (NSString *) status - withDelegate: (iCalPerson *) delegate; + withDelegate: (iCalPerson *) delegate + alarm: (iCalAlarm *) alarm; + - (NSException *) changeParticipationStatus: (NSString *) status withDelegate: (iCalPerson *) delegate + alarm: (iCalAlarm *) alarm forRecurrenceId: (NSCalendarDate *) _recurrenceId; // diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 620900854..64baf52d7 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -400,9 +400,9 @@ { currentUID = [currentAttendee uid]; if (currentUID) - [self _addOrUpdateEvent: newEvent - forUID: currentUID - owner: owner]; + [self _addOrUpdateEvent: newEvent + forUID: currentUID + owner: owner]; } [self sendEMailUsingTemplateNamed: @"Update" @@ -443,7 +443,7 @@ us = [user userSettings]; moduleSettings = [us objectForKey:@"Calendar"]; - // Check if the user prevented his account from beeing invited to events + // Check if the user prevented their account from beeing invited to events if (![user isResource] && [[moduleSettings objectForKey:@"PreventInvitations"] boolValue]) { // Check if the user have a whiteList @@ -637,10 +637,10 @@ if ([fbInfo count]) { - // If we always force the auto-accept if numberOfSimultaneousBookings == 0 (ie., no limit + // If we always force the auto-accept if numberOfSimultaneousBookings <= 0 (ie., no limit // is imposed) or if numberOfSimultaneousBookings is greater than the number of // overlapping events - if ([user numberOfSimultaneousBookings] == 0 || + if ([user numberOfSimultaneousBookings] <= 0 || [user numberOfSimultaneousBookings] > [fbInfo count]) { if (currentAttendee) @@ -734,7 +734,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent // the modification was actually NOT made on the master event if ([theEvent recurrenceId]) return; - + events = [[theEvent parent] events]; for (i = 0; i < [events count]; i++) @@ -743,12 +743,12 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent if ([e recurrenceId]) for (j = 0; j < [theAttendees count]; j++) if (shouldAdd) - [e addToAttendees: [theAttendees objectAtIndex: j]]; - else - [e removeFromAttendees: [theAttendees objectAtIndex: j]]; + [e addToAttendees: [theAttendees objectAtIndex: j]]; + else + [e removeFromAttendees: [theAttendees objectAtIndex: j]]; } } - + // // // @@ -803,14 +803,17 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent // We insert the attendees in all exception occurences, if // the attendees were added to the master event. [self _addOrDeleteAttendees: addedAttendees - inRecurrenceExceptionsForEvent: newEvent - add: YES]; + inRecurrenceExceptionsForEvent: newEvent + add: YES]; if ([changes sequenceShouldBeIncreased]) { [newEvent increaseSequence]; + // Update attendees calendars and send them an update - // notification by email + // notification by email. We ignore the newly added + // attendees as we don't want to send them invitation + // update emails [self _handleSequenceUpdateInEvent: newEvent ignoringAttendees: addedAttendees fromOldEvent: oldEvent]; @@ -1093,7 +1096,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent else { // We must REMOVE any SENT-BY here. This is important since if A accepted - // the event for B and then, B changes by himself his participation status, + // the event for B and then, B changes by theirself their participation status, // we don't want to keep the previous SENT-BY attribute there. [(NSMutableDictionary *)[otherAttendee attributes] removeObjectForKey: @"SENT-BY"]; } @@ -1191,7 +1194,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent else { // We must REMOVE any SENT-BY here. This is important since if A accepted - // the event for B and then, B changes by himself his participation status, + // the event for B and then, B changes by theirself their participation status, // we don't want to keep the previous SENT-BY attribute there. [(NSMutableDictionary *)[attendee attributes] removeObjectForKey: @"SENT-BY"]; } @@ -1208,7 +1211,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent delegatedUID = [otherDelegate uid]; if (delegatedUID) - // Delegate attendee is a local user; remove event from his calendar + // Delegate attendee is a local user; remove event from their calendar [self _removeEventFromUID: delegatedUID owner: [theOwnerUser login] withRecurrenceId: [event recurrenceId]]; @@ -1240,7 +1243,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent [event addToAttendees: delegate]; if (delegatedUID) - // Delegate attendee is a local user; add event to his calendar + // Delegate attendee is a local user; add event to their calendar [self _addOrUpdateEvent: event forUID: delegatedUID owner: [theOwnerUser login]]; @@ -1309,6 +1312,9 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent return ex; } +// +// +// - (NSDictionary *) _caldavSuccessCodeWithRecipient: (NSString *) recipient { NSMutableArray *element; @@ -1391,9 +1397,11 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent // - (NSException *) changeParticipationStatus: (NSString *) status withDelegate: (iCalPerson *) delegate + alarm: (iCalAlarm *) alarm { return [self changeParticipationStatus: status withDelegate: delegate + alarm: alarm forRecurrenceId: nil]; } @@ -1402,6 +1410,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent // - (NSException *) changeParticipationStatus: (NSString *) _status withDelegate: (iCalPerson *) delegate + alarm: (iCalAlarm *) alarm forRecurrenceId: (NSCalendarDate *) _recurrenceId { iCalCalendar *calendar; @@ -1479,7 +1488,18 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent // Over DAV, it'll be handled directly in PUTAction: if (![context request] || [[context request] handledByDefaultHandler] || [[[context request] requestHandlerKey] isEqualToString: @"Microsoft-Server-ActiveSync"]) - ex = [self saveCalendar: [event parent]]; + { + // If an alarm was specified, let's use it. This would happen if an attendee accepts/declines/etc. an + // event invitation and also sets an alarm along the way. This would happen ONLY from the web interface. + [event removeAllAlarms]; + + if (alarm) + { + [event addToAlarms: alarm]; + } + + ex = [self saveCalendar: [event parent]]; + } } } else @@ -1512,17 +1532,17 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent [v caseInsensitiveCompare: @"CLIENT"] == NSOrderedSame) b = NO; } - - // - // If we have to deal with Thunderbird/Lightning, we always send invitation - // reponses, as Lightning v2.6 (at least this version) sets SCHEDULE-AGENT - // to NONE/CLIENT when responding to an external invitation received by - // SOGo - so no invitation responses are ever sent by Lightning. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=865726 and - // https://bugzilla.mozilla.org/show_bug.cgi?id=997784 - // - userAgents = [[context request] headersForKey: @"User-Agent"]; - + + // + // If we have to deal with Thunderbird/Lightning, we always send invitation + // reponses, as Lightning v2.6 (at least this version) sets SCHEDULE-AGENT + // to NONE/CLIENT when responding to an external invitation received by + // SOGo - so no invitation responses are ever sent by Lightning. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=865726 and + // https://bugzilla.mozilla.org/show_bug.cgi?id=997784 + // + userAgents = [[context request] headersForKey: @"User-Agent"]; + for (i = 0; i < [userAgents count]; i++) { if ([[userAgents objectAtIndex: i] rangeOfString: @"Thunderbird"].location != NSNotFound && @@ -1533,7 +1553,6 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent } } - return b; } @@ -1594,7 +1613,9 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent { // The current user deletes the occurence; let the organizer know that // the user has declined this occurence. - [self changeParticipationStatus: @"DECLINED" withDelegate: nil + [self changeParticipationStatus: @"DECLINED" + withDelegate: nil + alarm: nil forRecurrenceId: recurrenceId]; send_receipt = NO; } @@ -1768,6 +1789,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent * Verify vCalendar for any inconsistency or missing attributes. * Currently only check if the events have an end date or a duration. * We also check for the default transparency parameters. + * We also check for broken ORGANIZER such as "ORGANIZER;:mailto:sogo3@example.com" * @param rq the HTTP PUT request */ - (void) _adjustEventsInRequestCalendar: (iCalCalendar *) rqCalendar @@ -1792,7 +1814,10 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent [self warnWithFormat: @"Invalid event: no end date; setting duration to %@", [event duration]]; } - + if ([event organizer] && ![[[event organizer] cn] length]) + { + [[event organizer] setCn: [[event organizer] rfc822Email]]; + } } } @@ -2157,12 +2182,14 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent { [self changeParticipationStatus: @"DECLINED" withDelegate: nil // FIXME (specify delegate?) + alarm: nil forRecurrenceId: [self _addedExDate: oldEvent newEvent: newEvent]]; } else if (attendee) { [self changeParticipationStatus: [attendee partStat] withDelegate: delegate + alarm: nil forRecurrenceId: recurrenceId]; } // All attendees and the organizer field were removed. Apple iCal does diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index f8822c061..ce600715b 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -644,8 +644,8 @@ // As much as we can, we try to use c_name == c_uid in order // to avoid tricky scenarios with some CalDAV clients. For example, // if Alice invites Bob (both use SOGo) and Bob accepts the invitation - // using Lightning before having refreshed his calendar, he'll end up - // with a duplicate of the event in his database tables. + // using Lightning before having refreshed their calendar, they'll end up + // with a duplicate of the event in their database tables. if (isNew) { newUid = nameInContainer; diff --git a/SoObjects/Appointments/SOGoComponentOccurence.h b/SoObjects/Appointments/SOGoComponentOccurence.h index 68b1d5369..ed77dd96c 100644 --- a/SoObjects/Appointments/SOGoComponentOccurence.h +++ b/SoObjects/Appointments/SOGoComponentOccurence.h @@ -25,6 +25,7 @@ @class NSException; +@class iCalAlarm; @class iCalCalendar; @class iCalPerson; @class iCalRepeatableEntityObject; @@ -37,7 +38,8 @@ - (BOOL) isNew; - (NSException *) changeParticipationStatus: (NSString *) newPartStat - withDelegate: (iCalPerson *) delegate; + withDelegate: (iCalPerson *) delegate + alarm: (iCalAlarm *) alarm; @end diff --git a/SoObjects/Appointments/SOGoComponentOccurence.m b/SoObjects/Appointments/SOGoComponentOccurence.m index 3b829d15e..f81a73f5a 100644 --- a/SoObjects/Appointments/SOGoComponentOccurence.m +++ b/SoObjects/Appointments/SOGoComponentOccurence.m @@ -215,6 +215,7 @@ they should be siblings or SOGoComponentOccurence the parent class of SOGoCalendarComponent... - (NSException *) changeParticipationStatus: (NSString *) newStatus withDelegate: (iCalPerson *) delegate + alarm: (iCalAlarm *) alarm { NSCalendarDate *date; @@ -222,6 +223,7 @@ return [container changeParticipationStatus: newStatus withDelegate: delegate + alarm: alarm forRecurrenceId: date]; } diff --git a/SoObjects/Appointments/SOGoFreeBusyObject.h b/SoObjects/Appointments/SOGoFreeBusyObject.h index 77b2f53ec..17f56dd51 100644 --- a/SoObjects/Appointments/SOGoFreeBusyObject.h +++ b/SoObjects/Appointments/SOGoFreeBusyObject.h @@ -1,6 +1,5 @@ /* - Copyright (C) 2007-2012 Inverse inc. - Copyright (C) 2000-2004 SKYRIX Software AG + Copyright (C) 2007-2014 Inverse inc. This file is part of SOGo diff --git a/SoObjects/Appointments/SOGoFreeBusyObject.m b/SoObjects/Appointments/SOGoFreeBusyObject.m index 18f08e10b..6624a2cfe 100644 --- a/SoObjects/Appointments/SOGoFreeBusyObject.m +++ b/SoObjects/Appointments/SOGoFreeBusyObject.m @@ -1,6 +1,5 @@ /* - Copyright (C) 2007-2012 Inverse inc. - Copyright (C) 2000-2004 SKYRIX Software AG + Copyright (C) 2007-2014 Inverse inc. This file is part of SOGo @@ -339,7 +338,7 @@ for (count = 0; count < max; count++) { calFolder = [folders objectAtIndex: count]; - if (![calFolder isSubscription] && [calFolder includeInFreeBusy]) + if ([calFolder includeInFreeBusy]) [infos addObjectsFromArray: [calFolder fetchFreeBusyInfosFrom: startDate to: endDate]]; } diff --git a/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings b/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings index 6bd6cc294..cdc39f607 100644 --- a/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings +++ b/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"Inviting the following persons is prohibited:" = "No está permitido invitar a las siguientes personas:"; "Personal Calendar" = "Calendario personal"; vevent_class0 = "(Evento público)"; vevent_class1 = "(Evento privado)"; diff --git a/SoObjects/Appointments/iCalAlarm+SOGo.h b/SoObjects/Appointments/iCalAlarm+SOGo.h new file mode 100644 index 000000000..2980f7bc6 --- /dev/null +++ b/SoObjects/Appointments/iCalAlarm+SOGo.h @@ -0,0 +1,37 @@ +/* iCalAlarm+SOGo.h - this file is part of SOGo + * + * Copyright (C) 2014 Inverse inc. + * + * This file 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; either version 2, or (at your option) + * any later version. + * + * This file 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +@class iCalRepeatableEntityObject; + +@interface iCalAlarm (SOGoExtensions) + ++ (id) alarmForEvent: (iCalRepeatableEntityObject *) theEntity + owner: (NSString *) theOwner + action: (NSString *) reminderAction + unit: (NSString *) reminderUnit + quantity: (NSString *) reminderQuantity + reference: (NSString *) reminderReference + reminderRelation: (NSString *) reminderRelation + emailAttendees: (BOOL) reminderEmailAttendees + emailOrganizer: (BOOL) reminderEmailOrganizer; + +@end diff --git a/SoObjects/Appointments/iCalAlarm+SOGo.m b/SoObjects/Appointments/iCalAlarm+SOGo.m new file mode 100644 index 000000000..c98c316db --- /dev/null +++ b/SoObjects/Appointments/iCalAlarm+SOGo.m @@ -0,0 +1,127 @@ +/* iCalAlarm+SOGo.m - this file is part of SOGo + * + * Copyright (C) 2014 Inverse inc. + * + * This file 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; either version 2, or (at your option) + * any later version. + * + * This file 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import "iCalAlarm+SOGo.h" + +#import +#import +#import + +#import + +#import +#import + +@implementation iCalAlarm (SOGoExtensions) + +- (void) _appendAttendees: (NSArray *) attendees + toEmailAlarm: (iCalAlarm *) alarm +{ + NSMutableArray *aAttendees; + int count, max; + iCalPerson *currentAttendee, *aAttendee; + + max = [attendees count]; + aAttendees = [NSMutableArray arrayWithCapacity: max]; + for (count = 0; count < max; count++) + { + currentAttendee = [attendees objectAtIndex: count]; + aAttendee = [iCalPerson elementWithTag: @"attendee"]; + [aAttendee setCn: [currentAttendee cn]]; + [aAttendee setEmail: [currentAttendee rfc822Email]]; + [aAttendees addObject: aAttendee]; + } + [alarm setAttendees: aAttendees]; +} + +- (void) _appendOrganizerToEmailAlarm: (iCalAlarm *) alarm + owner: (NSString *) uid +{ + NSDictionary *ownerIdentity; + iCalPerson *aAttendee; + + ownerIdentity = [[SOGoUser userWithLogin: uid roles: nil] + defaultIdentity]; + aAttendee = [iCalPerson elementWithTag: @"attendee"]; + [aAttendee setCn: [ownerIdentity objectForKey: @"fullName"]]; + [aAttendee setEmail: [ownerIdentity objectForKey: @"email"]]; + [alarm addChild: aAttendee]; +} + ++ (id) alarmForEvent: (iCalRepeatableEntityObject *) theEntity + owner: (NSString *) theOwner + action: (NSString *) reminderAction + unit: (NSString *) reminderUnit + quantity: (NSString *) reminderQuantity + reference: (NSString *) reminderReference + reminderRelation: (NSString *) reminderRelation + emailAttendees: (BOOL) reminderEmailAttendees + emailOrganizer: (BOOL) reminderEmailOrganizer +{ + iCalTrigger *aTrigger; + iCalAlarm *anAlarm; + NSString *aValue; + + anAlarm = [[self alloc] init]; + + aTrigger = [iCalTrigger elementWithTag: @"TRIGGER"]; + [aTrigger setValueType: @"DURATION"]; + [anAlarm setTrigger: aTrigger]; + + if ([reminderAction length] > 0 && [reminderUnit length] > 0) + { + [anAlarm setAction: [reminderAction uppercaseString]]; + if ([reminderAction isEqualToString: @"email"]) + { + [anAlarm removeAllAttendees]; + if (reminderEmailAttendees) + [anAlarm _appendAttendees: [theEntity attendees] + toEmailAlarm: anAlarm]; + if (reminderEmailOrganizer) + [anAlarm _appendOrganizerToEmailAlarm: anAlarm owner: theOwner]; + [anAlarm setSummary: [theEntity summary]]; + [anAlarm setComment: [theEntity comment]]; + } + + if ([reminderReference caseInsensitiveCompare: @"BEFORE"] == NSOrderedSame) + aValue = [NSString stringWithString: @"-P"]; + else + aValue = [NSString stringWithString: @"P"]; + + if ([reminderUnit caseInsensitiveCompare: @"MINUTES"] == NSOrderedSame || + [reminderUnit caseInsensitiveCompare: @"HOURS"] == NSOrderedSame) + aValue = [aValue stringByAppendingString: @"T"]; + + aValue = [aValue stringByAppendingFormat: @"%i%@", + [reminderQuantity intValue], + [reminderUnit substringToIndex: 1]]; + [aTrigger setSingleValue: aValue forKey: @""]; + [aTrigger setRelationType: reminderRelation]; + } + else + { + [anAlarm release]; + anAlarm = nil; + } + + return AUTORELEASE(anAlarm); +} + +@end diff --git a/SoObjects/Appointments/iCalCalendar+SOGo.m b/SoObjects/Appointments/iCalCalendar+SOGo.m index 74d660835..5127ead44 100644 --- a/SoObjects/Appointments/iCalCalendar+SOGo.m +++ b/SoObjects/Appointments/iCalCalendar+SOGo.m @@ -93,7 +93,7 @@ element = [elements objectAtIndex: 0]; else { - NSLog(@"ERROR: given calendar contains no elements: %@", self); + //NSLog(@"ERROR: given calendar contains no elements: %@", self); element = nil; } diff --git a/SoObjects/Contacts/BrazilianPortuguese.lproj/Localizable.strings b/SoObjects/Contacts/BrazilianPortuguese.lproj/Localizable.strings index 6dca00edd..8923eae93 100644 --- a/SoObjects/Contacts/BrazilianPortuguese.lproj/Localizable.strings +++ b/SoObjects/Contacts/BrazilianPortuguese.lproj/Localizable.strings @@ -1 +1,2 @@ "Personal Address Book" = "Livro de Endereços Pessoais"; +"Collected Address Book" = "Catálogos Coletados"; diff --git a/SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings b/SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings index 1476e55c4..c7e4f1213 100644 --- a/SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings +++ b/SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings @@ -1,2 +1,2 @@ -"SieveFolderName" = "Filtros"; "OtherUsersFolderName" = "Outros Usuários"; +"SharedFoldersName" = "Pastas Compartilhadas"; diff --git a/SoObjects/Mailer/GNUmakefile b/SoObjects/Mailer/GNUmakefile index a7afca3a4..b4725fc4f 100644 --- a/SoObjects/Mailer/GNUmakefile +++ b/SoObjects/Mailer/GNUmakefile @@ -98,7 +98,6 @@ Mailer_LOCALIZED_RESOURCE_FILES = Localizable.strings ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_INCLUDE_DIRS += $(shell xml2-config --cflags) -ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/wobundle.make diff --git a/SoObjects/Mailer/NSData+Mail.h b/SoObjects/Mailer/NSData+Mail.h index 7258be786..7be5af1a4 100644 --- a/SoObjects/Mailer/NSData+Mail.h +++ b/SoObjects/Mailer/NSData+Mail.h @@ -1,8 +1,6 @@ /* NSData+Mail.h - this file is part of SOGo * - * Copyright (C) 2007 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/Mailer/NSData+Mail.m b/SoObjects/Mailer/NSData+Mail.m index d54f28b3a..92f379ec4 100644 --- a/SoObjects/Mailer/NSData+Mail.m +++ b/SoObjects/Mailer/NSData+Mail.m @@ -1,9 +1,6 @@ /* NSData+Mail.m - this file is part of SOGo * - * Copyright (C) 2007-2008 Inverse inc. - * - * Author: Wolfgang Sourdeau - * Ludovic Marcotte + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,7 +49,7 @@ else { decodedData = nil; - NSLog (@"encoding '%@' unknown, returning nil data", realEncoding); + //NSLog (@"encoding '%@' unknown, returning nil data", realEncoding); } } else diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 24b84e8bd..6967a6262 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -629,7 +629,7 @@ static NSString *userAgent = nil; folder = [imap4 imap4FolderNameForURL: [container imap4URL]]; result = [client append: message toFolder: folder - withFlags: [NSArray arrayWithObjects: @"seen", @"draft", nil]]; + withFlags: [NSArray arrayWithObjects: @"draft", nil]]; if ([[result objectForKey: @"result"] boolValue]) { if (IMAP4ID > -1) @@ -1217,13 +1217,13 @@ static NSString *userAgent = nil; if (!isHTML) { - [map setObject: contentTypeValue forKey: @"content-type"]; + [message setHeader: contentTypeValue forKey: @"content-type"]; body = text; } else { body = [[[NGMimeMultipartBody alloc] initWithPart: message] autorelease]; - [map addObject: MultiAlternativeType forKey: @"content-type"]; + [message setHeader: MultiAlternativeType forKey: @"content-type"]; // Get the text part from it and add it [body addBodyPart: [self plainTextBodyPartForText]]; diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index 5bc3ff2ae..97057a1c4 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -40,6 +40,7 @@ #import #import #import +#import #import #import @@ -664,53 +665,67 @@ static NSString *inboxFolderName = @"INBOX"; - (NSDictionary *) imapFolderGUIDs { - NSDictionary *result, *nresult, *folderData; + NSDictionary *result, *nresult, *namespaceDict; NSMutableDictionary *folders; NGImap4Client *client; - SOGoUserDefaults *ud; NSArray *folderList; NSEnumerator *e; NSString *guid; id object; - BOOL subscribedOnly; + BOOL hasAnnotatemore; - ud = [[context activeUser] userDefaults]; - subscribedOnly = [ud mailShowSubscribedFoldersOnly]; - - folderList = [[self imap4Connection] allFoldersForURL: [self imap4URL] - onlySubscribedFolders: subscribedOnly]; + folderList = [self allFolderPaths]; folders = [NSMutableDictionary dictionary]; client = [[self imap4Connection] client]; - result = [client annotation: @"*" entryName: @"/comment" attributeName: @"value.priv"]; + namespaceDict = [client namespace]; + hasAnnotatemore = [self hasCapability: @"annotatemore"]; + if (hasAnnotatemore) + result = [client annotation: @"*" entryName: @"/comment" attributeName: @"value.priv"]; + else + result = [client lstatus: @"*" flags: [NSArray arrayWithObjects: @"x-guid", nil]]; + e = [folderList objectEnumerator]; - - while (object = [e nextObject]) + + while ((object = [e nextObject])) { - guid = [[[[result objectForKey: @"FolderList"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"/comment"] objectForKey: @"value.priv"]; - + if (hasAnnotatemore) + guid = [[[[result objectForKey: @"FolderList"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"/comment"] objectForKey: @"value.priv"]; + else + guid = [[[result objectForKey: @"status"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"x-guid"]; + if (!guid) { - guid = [[NSProcessInfo processInfo] globallyUniqueString]; - nresult = [client annotation: [object substringFromIndex: 1] entryName: @"/comment" attributeName: @"value.priv" attributeValue: guid]; - - if (![[nresult objectForKey: @"result"] boolValue]) + // Don't generate a GUID for "Other users" and "Shared" namespace folders - user foldername instead + if ([[object substringFromIndex: 1] isEqualToString: [[[[namespaceDict objectForKey: @"other users"] lastObject] objectForKey: @"prefix"] substringFromIndex: 1]] || + [[object substringFromIndex: 1] isEqualToString: [[[[namespaceDict objectForKey: @"shared"] lastObject] objectForKey: @"prefix"] substringFromIndex: 1]]) { - // Need to implement X-GUID query for Dovecot - this requires modification in SOPE to support following command: - // 1 list "" "*" return (status (x-guid)) -> this would avoid firing a command per folder to IMAP - nresult = [client status: [object substringFromIndex: 1] flags: [NSArray arrayWithObject: @"x-guid"]]; - guid = [nresult objectForKey: @"x-guid"]; - if (!guid) - { - guid = [NSString stringWithFormat: @"%@", [object substringFromIndex: 1]]; - } + [folders setObject: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]] forKey: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]]]; + continue; } + + // if folder doesn't exists - ignore it + nresult = [client status: [object substringFromIndex: 1] + flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]; + if (![[nresult valueForKey: @"result"] boolValue]) + continue; + + if (hasAnnotatemore) + { + guid = [[NSProcessInfo processInfo] globallyUniqueString]; + nresult = [client annotation: [object substringFromIndex: 1] entryName: @"/comment" attributeName: @"value.priv" attributeValue: guid]; + } + + // setannotation failed or annotatemore is not available + if (![[nresult objectForKey: @"result"] boolValue] || !hasAnnotatemore) + guid = [NSString stringWithFormat: @"%@", [object substringFromIndex: 1]]; } - [folders setObject: guid forKey: [object substringFromIndex: 1]]; + [folders setObject: [NSString stringWithFormat: @"folder%@", guid] forKey: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]]]; + } return folders; diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m index 73967efe0..863491e2e 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SoObjects/Mailer/SOGoMailBaseObject.m @@ -43,10 +43,6 @@ @implementation SOGoMailBaseObject -#if 0 -static BOOL debugOn = YES; -#endif - - (id) initWithImap4URL: (NSURL *) _url inContainer: (id) _container { diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 3607b9dd2..d83ca78a6 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -1069,7 +1069,11 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) NSException *error; if ([self imap4Connection]) - error = [imap4 deleteMailboxAtURL: [self imap4URL]]; + { + error = [imap4 deleteMailboxAtURL: [self imap4URL]]; + if (!error) + [[imap4 client] unsubscribe: [[self imap4URL] path]]; + } else error = [NSException exceptionWithName: @"SOGoMailException" reason: @"IMAP connection is invalid" diff --git a/SoObjects/SOGo/BSONCodec.m b/SoObjects/SOGo/BSONCodec.m index 58625a59f..99eee87c4 100644 --- a/SoObjects/SOGo/BSONCodec.m +++ b/SoObjects/SOGo/BSONCodec.m @@ -11,6 +11,10 @@ #import #import +#import + +static NSMutableDictionary *timezoneCache = nil; + #define BSONTYPE(tag,className) [className class], [NSNumber numberWithChar: (tag)] #ifndef objc_msgSend @@ -579,11 +583,38 @@ static NSDictionary *BSONTypes() + (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID { - NSString *v; - - v = [NSString BSONFragment: data at: base ofType: 0x02]; + NSTimeZone *tz; + NSString *key; - return [NSCalendarDate dateWithString: v - calendarFormat: @"%Y-%m-%d %H:%M:%S %Z"]; + unsigned int year, month, day, hour, minute, second; + char timezone[64]; + const char *v; + + if (!timezoneCache) + timezoneCache = [[NSMutableDictionary alloc] init]; + + v = [[NSString BSONFragment: data at: base ofType: 0x02] cStringUsingEncoding: NSASCIIStringEncoding]; + + sscanf(v, "%d-%d-%d %d:%d:%d %s", &year, &month, &day, &hour, &minute, &second, timezone); + + key = [NSString stringWithFormat: @"%s", timezone]; + + if (!(tz = [timezoneCache objectForKey: key])) + { + tz = [NSTimeZone timeZoneWithAbbreviation: key]; + + if (tz) + [timezoneCache setObject: tz forKey: key]; + else + [self errorWithFormat: @"BSON error: timezone (%@) not found when deserializing BSON data", key]; + } + + return [NSCalendarDate dateWithYear: year + month: month + day: day + hour: hour + minute: minute + second: second + timeZone: tz]; } @end diff --git a/SoObjects/SOGo/GNUmakefile b/SoObjects/SOGo/GNUmakefile index f1ee391bd..70b458001 100644 --- a/SoObjects/SOGo/GNUmakefile +++ b/SoObjects/SOGo/GNUmakefile @@ -11,6 +11,8 @@ SOGo_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) #SOGo_INSTALL_DIR = $(SOGO_LIBDIR) SOGo_INSTALL_DIR = $(DESTDIR)$(GNUSTEP_$(GNUSTEP_INSTALLATION_DOMAIN)_FRAMEWORKS) +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo + SOGo_HEADER_FILES = \ SOGoBuild.h \ SOGoProductLoader.h \ @@ -200,6 +202,7 @@ ADDITIONAL_LDFLAGS += -lmemcached ifneq ($(FHS_INSTALL_ROOT),) GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include endif +GNUSTEP_TARGET_LDIR=sogo include $(GNUSTEP_MAKEFILES)/framework.make include $(GNUSTEP_MAKEFILES)/library.make include $(GNUSTEP_MAKEFILES)/tool.make diff --git a/SoObjects/SOGo/NSObject+Utilities.h b/SoObjects/SOGo/NSObject+Utilities.h index 469eab8b9..102ab7ef3 100644 --- a/SoObjects/SOGo/NSObject+Utilities.h +++ b/SoObjects/SOGo/NSObject+Utilities.h @@ -40,6 +40,8 @@ - (NSString *) labelForKey: (NSString *) key inContext: (WOContext *) context; ++ (void) memoryStatistics; + @end #endif /* NSOBJECT+UTILITIES_H */ diff --git a/SoObjects/SOGo/NSObject+Utilities.m b/SoObjects/SOGo/NSObject+Utilities.m index 2f9ed96cd..3dca1f0f5 100644 --- a/SoObjects/SOGo/NSObject+Utilities.m +++ b/SoObjects/SOGo/NSObject+Utilities.m @@ -22,6 +22,7 @@ #import #import +#import #import #import @@ -122,4 +123,33 @@ return label; } +// +// Set SOGoDebugLeaks = YES in your defaults to enable. +// ++ (void) memoryStatistics +{ + Class *classList = GSDebugAllocationClassList (); + Class *pointer; + int i, count, total, peak; + NSString *className; + + pointer = classList; + i = 0; + + printf("Class count total peak\n"); + while (pointer[i] != NULL) + { + className = NSStringFromClass (pointer[i]); + count = GSDebugAllocationCount (pointer[i]); + total = GSDebugAllocationTotal (pointer[i]); + peak = GSDebugAllocationPeak (pointer[i]); + + printf("%s %d %d %d\n", [className UTF8String], count, total, peak); + i++; + } + NSZoneFree(NSDefaultMallocZone(), classList); + + printf("Done!\n"); +} + @end diff --git a/SoObjects/SOGo/SOGoCASSession.h b/SoObjects/SOGo/SOGoCASSession.h index ade1cf0a5..e7d6fabb9 100644 --- a/SoObjects/SOGo/SOGoCASSession.h +++ b/SoObjects/SOGo/SOGoCASSession.h @@ -1,8 +1,6 @@ /* SOGoCASSession.h - this file is part of SOGo * - * Copyright (C) 2010 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2010-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoCASSession.m b/SoObjects/SOGo/SOGoCASSession.m index 4d684c382..8c77df29b 100644 --- a/SoObjects/SOGo/SOGoCASSession.m +++ b/SoObjects/SOGo/SOGoCASSession.m @@ -1,8 +1,6 @@ /* SOGoCASSession.m - this file is part of SOGo * - * Copyright (C) 2010 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2010-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoCache.h b/SoObjects/SOGo/SOGoCache.h index 648fc4b60..69ef6f942 100644 --- a/SoObjects/SOGo/SOGoCache.h +++ b/SoObjects/SOGo/SOGoCache.h @@ -132,6 +132,7 @@ - (NSDictionary *) saml2LoginDumpsForIdentifier: (NSString *) identifier; - (void) setSaml2LoginDumps: (NSDictionary *) dump forIdentifier: (NSString *) identifier; +- (void) removeSAML2LoginDumpsForIdentifier: (NSString *) identifier; // // ACL caching support diff --git a/SoObjects/SOGo/SOGoCache.m b/SoObjects/SOGo/SOGoCache.m index dac0b2d85..13e171e09 100644 --- a/SoObjects/SOGo/SOGoCache.m +++ b/SoObjects/SOGo/SOGoCache.m @@ -31,8 +31,8 @@ * +defaults value = NSDictionary instance > user's defaults * +settings value = NSDictionary instance > user's settings * +attributes value = NSMutableDictionary instance > user's LDAP attributes - * +failedlogins value = - * +messagesubmissions value = + * +failedlogins value = NSDictionary instance holding the failed count and the date of the first failed authentication + * +messagesubmissions value = NSDictionary instance holding the number of messages sent, and number of recipients * +dn value = NSString instance > cached user's DN * +acl value = NSDictionary instance > ACLs on an object at specified path * + value = NSString instance (array components separated by ",") or group member logins for a specific group in domain @@ -40,8 +40,7 @@ * cas-ticket:< > value = * cas-pgtiou:< > value = * session:< > value = - * +failedlogins value = NSDictionary instance holding the failed count and the date of the first failed authentication - * +messagesubmissions value = NSDictionary instance holding the number of messages sent, and number of recipients + * saml2-login:< > value = */ @@ -674,11 +673,13 @@ static memcached_st *handle = NULL; { key = [NSString stringWithFormat: @"cas-ticket:%@", ticket]; [self removeValueForKey: key]; - [self debugWithFormat: @"Removed session: %@", session]; + [self debugWithFormat: @"Removed CAS session: %@", session]; } } +// // SAML2 support +// - (NSDictionary *) saml2LoginDumpsForIdentifier: (NSString *) identifier { NSString *key, *jsonString; @@ -699,6 +700,16 @@ static memcached_st *handle = NULL; [self setValue: [dump jsonRepresentation] forKey: key]; } +- (void) removeSAML2LoginDumpsForIdentifier: (NSString *) identifier +{ + NSString *key; + + key = [NSString stringWithFormat: @"saml2-login:%@", identifier]; + + [self removeValueForKey: key]; + [self debugWithFormat: @"Removed SAML2 session for identifier: %@", identifier]; +} + // // ACL caching code // diff --git a/SoObjects/SOGo/SOGoCacheGCSObject.h b/SoObjects/SOGo/SOGoCacheGCSObject.h index 90f7d1ba1..b456c1775 100644 --- a/SoObjects/SOGo/SOGoCacheGCSObject.h +++ b/SoObjects/SOGo/SOGoCacheGCSObject.h @@ -67,8 +67,8 @@ typedef enum { - (NSDictionary *) lookupRecord: (NSString *) path newerThanVersion: (NSInteger) startVersion; -- (NSArray *) folderList: (NSString *) deviceId - newerThanVersion: (NSInteger) startVersion; +- (NSArray *) cacheEntriesForDeviceId: (NSString *) deviceId + newerThanVersion: (NSInteger) startVersion; - (void) setObjectType: (SOGoCacheObjectType) newObjectType; - (SOGoCacheObjectType) objectType; /* message, fai, folder */ diff --git a/SoObjects/SOGo/SOGoCacheGCSObject.m b/SoObjects/SOGo/SOGoCacheGCSObject.m index 0b3ba25e8..a2251173a 100644 --- a/SoObjects/SOGo/SOGoCacheGCSObject.m +++ b/SoObjects/SOGo/SOGoCacheGCSObject.m @@ -36,6 +36,7 @@ #import #import #import +#import #import #import #import @@ -96,10 +97,29 @@ static EOAttribute *textColumn = nil; - (void) dealloc { + //NSLog(@"SOGoCacheGCSObject: -dealloc for name: %@", nameInContainer); [tableUrl release]; [super dealloc]; } ++ (id) objectWithName: (NSString *) key inContainer: (id) theContainer +{ + SOGoCache *cache; + id o; + + cache = [SOGoCache sharedCache]; + o = [cache objectNamed: key inContainer: theContainer]; + + if (!o) + { + o = [super objectWithName: key inContainer: theContainer]; + //NSLog(@"Caching object with key: %@", key); + [cache registerObject: o withName: key inContainer: theContainer]; + } + + return o; +} + - (void) setTableUrl: (NSURL *) newTableUrl { ASSIGN (tableUrl, newTableUrl); @@ -250,7 +270,7 @@ static EOAttribute *textColumn = nil; newParentPath = NULL; sql = [NSMutableString stringWithFormat: @"UPDATE %@" - @" SET c_path = '%@'", + @" SET c_path = '/%@'", [self tableName], newPath]; if (newParentPath) @@ -375,9 +395,8 @@ static EOAttribute *textColumn = nil; return record; } -// get a list of all folders -- (NSArray *) folderList: (NSString *) deviceId - newerThanVersion: (NSInteger) startVersion +- (NSArray *) cacheEntriesForDeviceId: (NSString *) deviceId + newerThanVersion: (NSInteger) startVersion { NSMutableArray *recordsOut; NSArray *records; @@ -392,16 +411,22 @@ static EOAttribute *textColumn = nil; tableName = [self tableName]; adaptor = [self tableChannelAdaptor]; - pathValue = [adaptor formatValue: [NSString stringWithFormat: @"/%@+folder%", deviceId] + pathValue = [adaptor formatValue: [NSString stringWithFormat: @"/%@", deviceId] forAttribute: textColumn]; /* query */ sql = [NSMutableString stringWithFormat: - @"SELECT * FROM %@ WHERE c_path LIKE %@ AND c_deleted <> 1", - tableName, pathValue]; + @"SELECT * FROM %@ WHERE c_type = %d AND c_deleted <> 1", tableName, objectType]; + if (startVersion > -1) [sql appendFormat: @" AND c_version > %d", startVersion]; + if (deviceId) { + pathValue = [adaptor formatValue: [NSString stringWithFormat: @"/%@%", deviceId] + forAttribute: textColumn]; + [sql appendFormat: @" AND c_path like %@", pathValue]; + } + /* execution */ records = [self performSQLQuery: sql]; diff --git a/SoObjects/SOGo/SOGoDefaults.plist b/SoObjects/SOGo/SOGoDefaults.plist index 17388f261..d0d230c43 100644 --- a/SoObjects/SOGo/SOGoDefaults.plist +++ b/SoObjects/SOGo/SOGoDefaults.plist @@ -68,6 +68,8 @@ SOGoDraftsFolderName = "Drafts"; SOGoTrashFolderName = "Trash"; + SOGoMailAutoSave = "5"; + SOGoCalendarDefaultCategoryColor = "#aaa"; SOGoCalendarShouldDisplayWeekend = YES; SOGoCalendarEventsDefaultClassification = "PUBLIC"; diff --git a/SoObjects/SOGo/SOGoDomainDefaults.h b/SoObjects/SOGo/SOGoDomainDefaults.h index 00a79cfe9..4743917af 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.h +++ b/SoObjects/SOGo/SOGoDomainDefaults.h @@ -1,8 +1,6 @@ /* SOGoDomainDefaults.h - this file is part of SOGo * - * Copyright (C) 2009-2013 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2009-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoDomainDefaults.m b/SoObjects/SOGo/SOGoDomainDefaults.m index 1a577c3f6..35a078b3f 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.m +++ b/SoObjects/SOGo/SOGoDomainDefaults.m @@ -2,8 +2,6 @@ * * Copyright (C) 2009-2014 Inverse inc. * - * Author: Wolfgang Sourdeau - * * This file 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; either version 2, or (at your option) diff --git a/SoObjects/SOGo/SOGoFolder.h b/SoObjects/SOGo/SOGoFolder.h index 186036db3..eb435a501 100644 --- a/SoObjects/SOGo/SOGoFolder.h +++ b/SoObjects/SOGo/SOGoFolder.h @@ -1,6 +1,6 @@ /* SOGoFolder.h - this file is part of SOGo * - * Copyright (C) 2007-2013 Inverse inc. + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index a27466cdd..b089c258a 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -1,8 +1,6 @@ /* SOGoFolder.m - this file is part of SOGo * - * Copyright (C) 2007-2011 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoGCSFolder.h b/SoObjects/SOGo/SOGoGCSFolder.h index 806be9105..9b8de6b35 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.h +++ b/SoObjects/SOGo/SOGoGCSFolder.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG - Copyright (C) 2006-2014 Inverse inc. + Copyright (C) 2006-2015 Inverse inc. This file is part of SOGo. diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index c8a2bccea..9f77359e9 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -282,41 +282,40 @@ static NSArray *childRecordFields = nil; return value; } -- (void) _setDisplayNameFromRow: (NSDictionary *) row +- (NSString *) _displayNameFromRow: (NSDictionary *) row { - NSString *primaryDN; + NSString *name, *primaryDN; + name = nil; primaryDN = [row objectForKey: @"c_foldername"]; if ([primaryDN length]) { - DESTROY(displayName); - if ([primaryDN isEqualToString: [container defaultFolderName]]) - displayName = [self labelForKey: primaryDN - inContext: context]; + name = [self labelForKey: primaryDN + inContext: context]; else - displayName = primaryDN; - - RETAIN(displayName); + name = primaryDN; } + + return name; } /* This method fetches the display name defined by the owner, but is also the - fallback when a subscriber has not redefined the display name yet in his + fallback when a subscriber has not redefined the display name yet in their environment. */ -- (void) _fetchDisplayNameFromOwner +- (NSString *) _displayNameFromOwner { GCSChannelManager *cm; EOAdaptorChannel *fc; NSURL *folderLocation; - NSString *sql; + NSString *name, *sql; NSArray *attrs; NSDictionary *row; + name = nil; cm = [GCSChannelManager defaultChannelManager]; - folderLocation - = [[GCSFolderManager defaultFolderManager] folderInfoLocation]; + folderLocation = [[GCSFolderManager defaultFolderManager] folderInfoLocation]; fc = [cm acquireOpenChannelForURL: folderLocation]; if (fc) { @@ -324,33 +323,34 @@ static NSArray *childRecordFields = nil; // performing the query. This could have unexpected results. NS_DURING { - sql - = [NSString stringWithFormat: (@"SELECT c_foldername FROM %@" - @" WHERE c_path = '%@'"), - [folderLocation gcsTableName], ocsPath]; + sql = [NSString stringWithFormat: (@"SELECT c_foldername FROM %@" + @" WHERE c_path = '%@'"), + [folderLocation gcsTableName], ocsPath]; [fc evaluateExpressionX: sql]; attrs = [fc describeResults: NO]; row = [fc fetchAttributes: attrs withZone: NULL]; if (row) - [self _setDisplayNameFromRow: row]; + name = [self _displayNameFromRow: row]; [fc cancelFetch]; [cm releaseChannel: fc]; } NS_HANDLER; NS_ENDHANDLER; } + + return name; } -- (void) _fetchDisplayNameFromSubscriber +- (NSString *) _displayNameFromSubscriber { NSDictionary *ownerIdentity, *folderSubscriptionValues; - NSString *displayNameFormat; + NSString *name, *displayNameFormat; SOGoDomainDefaults *dd; - displayName = [self folderPropertyValueInCategory: @"FolderDisplayNames"]; - if (!displayName) + name = [self folderPropertyValueInCategory: @"FolderDisplayNames"]; + if (!name) { - [self _fetchDisplayNameFromOwner]; + name = [self _displayNameFromOwner]; // We MUST NOT use SOGoUser instances here (by calling -primaryIdentity) // as it'll load user defaults and user settings which is _very costly_ @@ -358,17 +358,17 @@ static NSArray *childRecordFields = nil; ownerIdentity = [[SOGoUserManager sharedUserManager] contactInfosForUserWithUIDorEmail: owner]; - folderSubscriptionValues = [[NSDictionary alloc] initWithObjectsAndKeys: displayName, @"FolderName", + folderSubscriptionValues = [[NSDictionary alloc] initWithObjectsAndKeys: name, @"FolderName", [ownerIdentity objectForKey: @"cn"], @"UserName", [ownerIdentity objectForKey: @"c_email"], @"Email", nil]; dd = [[context activeUser] domainDefaults]; displayNameFormat = [dd subscriptionFolderFormat]; - displayName = [folderSubscriptionValues keysWithFormat: displayNameFormat]; + name = [folderSubscriptionValues keysWithFormat: displayNameFormat]; } - [displayName retain]; + return name; } - (NSString *) displayName @@ -376,14 +376,14 @@ static NSArray *childRecordFields = nil; if (!displayName) { if (activeUserIsOwner) - [self _fetchDisplayNameFromOwner]; + displayName = [self _displayNameFromOwner]; else { - [self _fetchDisplayNameFromSubscriber]; - + displayName = [self _displayNameFromSubscriber]; if (!displayName) - [self _fetchDisplayNameFromOwner]; + displayName = [self _displayNameFromOwner]; } + [displayName retain]; } return displayName; @@ -895,7 +895,7 @@ static NSArray *childRecordFields = nil; allUsers = [NSMutableArray arrayWithArray: [aGroup members]]; // We remove the active user from the group (if present) in order to - // not subscribe him to his own resource! + // not subscribe him to their own resource! [allUsers removeObject: [context activeUser]]; } else @@ -949,7 +949,7 @@ static NSArray *childRecordFields = nil; forKey: @"FolderShowAlarms"]; } - [self setFolderPropertyValue: [self displayName] + [self setFolderPropertyValue: [self _displayNameFromSubscriber] inCategory: @"FolderDisplayNames" settings: us]; @@ -1165,7 +1165,14 @@ static NSArray *childRecordFields = nil; int syncTokenInt; fields = [NSMutableArray arrayWithObjects: @"c_name", @"c_component", - @"c_creationdate", @"c_lastmodified", nil]; + @"c_creationdate", @"c_lastmodified", nil]; + + if ([[self folderType] isEqualToString: @"Appointment"]) + { + [fields addObject: @"c_enddate"]; + [fields addObject: @"c_cycleenddate"]; + } + addFields = [[properties allValues] objectEnumerator]; while ((currentField = [addFields nextObject])) if ([currentField length]) @@ -1181,7 +1188,9 @@ static NSArray *childRecordFields = nil; if (theStartDate) { EOQualifier *sinceDateQualifier = [EOQualifier qualifierWithQualifierFormat: - @"c_creationdate > %d", (int)[theStartDate timeIntervalSince1970]]; + @"(c_enddate > %d OR c_enddate = NULL) OR (c_iscycle = 1 and (c_cycleenddate > %d OR c_cycleenddate = NULL))", + (int)[theStartDate timeIntervalSince1970], + (int)[theStartDate timeIntervalSince1970]]; qualifier = [[EOAndQualifier alloc] initWithQualifiers: sinceDateQualifier, qualifier, nil]; @@ -1194,7 +1203,7 @@ static NSArray *childRecordFields = nil; qualifier = [EOQualifier qualifierWithQualifierFormat: @"c_lastmodified > %d and c_deleted == 1", syncTokenInt]; - fields = [NSMutableArray arrayWithObjects: @"c_name", @"c_deleted", nil]; + fields = [NSMutableArray arrayWithObjects: @"c_name", @"c_lastmodified", @"c_deleted", nil]; [mRecords addObjectsFromArray: [self _fetchFields: fields withQualifier: qualifier ignoreDeleted: NO]]; @@ -1211,7 +1220,9 @@ static NSArray *childRecordFields = nil; if (theStartDate) { EOQualifier *sinceDateQualifier = [EOQualifier qualifierWithQualifierFormat: - @"c_creationdate > %d", (int)[theStartDate timeIntervalSince1970]]; + @"(c_enddate > %d OR c_enddate = NULL) OR (c_iscycle = 1 and (c_cycleenddate > %d OR c_cycleenddate = NULL))", + (int)[theStartDate timeIntervalSince1970], + (int)[theStartDate timeIntervalSince1970]]; qualifier = [[EOAndQualifier alloc] initWithQualifiers: sinceDateQualifier, qualifier, nil]; diff --git a/SoObjects/SOGo/SOGoMailer.h b/SoObjects/SOGo/SOGoMailer.h index 6ebc0ef7d..6f82092e2 100644 --- a/SoObjects/SOGo/SOGoMailer.h +++ b/SoObjects/SOGo/SOGoMailer.h @@ -1,8 +1,6 @@ /* SOGoMailer.h - this file is part of SOGo * - * Copyright (C) 2007 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoMailer.m b/SoObjects/SOGo/SOGoMailer.m index bbf59540d..edf341bfc 100644 --- a/SoObjects/SOGo/SOGoMailer.m +++ b/SoObjects/SOGo/SOGoMailer.m @@ -1,8 +1,6 @@ /* SOGoMailer.m - this file is part of SOGo * - * Copyright (C) 2007-2013 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -215,7 +213,7 @@ } NS_HANDLER { - NSLog(@"Could not connect to the SMTP server %@ on port %d", host, port); + [self errorWithFormat: @"Could not connect to the SMTP server %@ on port %d", host, port]; result = [NSException exceptionWithHTTPStatus: 500 reason: @"cannot send message:" @" (smtp) error when connecting"]; diff --git a/SoObjects/SOGo/SOGoObject.h b/SoObjects/SOGo/SOGoObject.h index dafd5f06e..8ea1c6b77 100644 --- a/SoObjects/SOGo/SOGoObject.h +++ b/SoObjects/SOGo/SOGoObject.h @@ -1,14 +1,15 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG + Copyright (C) 2006-2015 Inverse inc. - This file is part of OpenGroupware.org. + This file is part of SOGo. - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo 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 Lesser General Public License for more details. diff --git a/SoObjects/SOGo/SOGoObject.m b/SoObjects/SOGo/SOGoObject.m index 716e8f194..3f3afcb9b 100644 --- a/SoObjects/SOGo/SOGoObject.m +++ b/SoObjects/SOGo/SOGoObject.m @@ -1,7 +1,7 @@ /* SOGoObject.m - this file is part of SOGo * * Copyright (C) 2004-2005 SKYRIX Software AG - * Copyright (C) 2006-2013 Inverse inc. + * Copyright (C) 2006-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoParentFolder.h b/SoObjects/SOGo/SOGoParentFolder.h index 73ee5deeb..97cf89f8e 100644 --- a/SoObjects/SOGo/SOGoParentFolder.h +++ b/SoObjects/SOGo/SOGoParentFolder.h @@ -1,6 +1,6 @@ /* SOGoParentFolder.h - this file is part of SOGo * - * Copyright (C) 2006-2014 Inverse inc. + * Copyright (C) 2006-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index 164296b83..501f90f9f 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -1,8 +1,6 @@ /* SOGoParentFolder.m - this file is part of SOGo * - * Copyright (C) 2006-2009 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2006-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -294,6 +292,18 @@ static SoSecurityManager *sm = nil; subscribedFolder = [subFolderClass folderWithSubscriptionReference: sourceKey inContainer: self]; + + // We check with -ocsFolderForPath if the folder also exists in the database. + // This is important because user A could delete folder X, and user B has subscribed to it. + // If the "default roles" are enabled for calendars/address books, -validatePersmission:.. will + // work (grabbing the default role) and the deleted resource will be incorrectly returned. + // + // FIXME - 2015/01/29 - this fix (24c6c8c91d421594bd51f07904d4cd3911cd187c) was reverted. Normally, we should add + // [subscribedFolder ocsFolderForPath: [subscribedFolder ocsPath]] to check the existence of the folder but it causes + // massive SQL traffic. + // + // The proper fix would be to check upon login and only upon login if GCS folders that we're subscribed to are still existent. + // if (subscribedFolder && ![sm validatePermission: SOGoPerm_AccessObject onObject: subscribedFolder diff --git a/SoObjects/SOGo/SOGoSAML2Metadata.xml b/SoObjects/SOGo/SOGoSAML2Metadata.xml new file mode 100644 index 000000000..478f786f5 --- /dev/null +++ b/SoObjects/SOGo/SOGoSAML2Metadata.xml @@ -0,0 +1,27 @@ + + + + %{certificate}%{certificate} + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + diff --git a/SoObjects/SOGo/SOGoSAML2Session.h b/SoObjects/SOGo/SOGoSAML2Session.h index 00a3c4945..0592f38e1 100644 --- a/SoObjects/SOGo/SOGoSAML2Session.h +++ b/SoObjects/SOGo/SOGoSAML2Session.h @@ -1,8 +1,6 @@ /* SOGoSAML2Session.h - this file is part of SOGo * - * Copyright (C) 2012 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2012-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,9 +37,15 @@ NSString *login; NSString *identifier; NSString *assertion; + NSString *identity; + NSString *session; } -+ (NSString *) metadataInContext: (WOContext *) context; ++ (LassoServer *) lassoServerInContext: (WOContext *) context; + ++ (NSString *) metadataInContext: (WOContext *) context + certificate: (NSString *) certificate; + + (NSString *) authenticationURLInContext: (WOContext *) context; + (SOGoSAML2Session *) SAML2SessionInContext: (WOContext *) context; @@ -54,6 +58,8 @@ - (NSString *) login; - (NSString *) identifier; - (NSString *) assertion; +- (NSString *) identity; +- (NSString *) session; @end diff --git a/SoObjects/SOGo/SOGoSAML2Session.m b/SoObjects/SOGo/SOGoSAML2Session.m index 9fda46089..96ced1516 100644 --- a/SoObjects/SOGo/SOGoSAML2Session.m +++ b/SoObjects/SOGo/SOGoSAML2Session.m @@ -1,8 +1,6 @@ /* SOGoSAML2Session.m - this file is part of SOGo * - * Copyright (C) 2012 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2012-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,6 +46,28 @@ #import "SOGoSAML2Session.h" +@interface NSString (SOGoCertificateExtension) + +- (NSString *) cleanedUpCertificate; + +@end + +@implementation NSString (SOGoCertificateExtension) + +- (NSString *) cleanedUpCertificate +{ + NSMutableArray *a; + + a = [NSMutableArray arrayWithArray: [self componentsSeparatedByString: @"\n"]]; + [a removeObjectAtIndex: 0]; + [a removeLastObject]; + [a removeLastObject]; + + return [a componentsJoinedByString: @""]; +} + +@end + @interface WOContext (SOGoSAML2Extension) - (NSString *) SAML2ServerURLString; @@ -85,8 +105,7 @@ static NSMapTable *serverTable = nil; lasso_init (); } -static LassoServer * -LassoServerInContext (WOContext *context) ++ (LassoServer *) lassoServerInContext: (WOContext *) context { NSString *urlString, *metadata, *filename, *keyContent, *certContent, *idpKeyFilename, *idpCertFilename; @@ -102,7 +121,7 @@ LassoServerInContext (WOContext *context) filename = [sd SAML2PrivateKeyLocation]; if (!filename) [NSException raise: NSInvalidArgumentException - format: @"'SAML2PrivateKeyLocation' not set"]; + format: @"'SOGoSAML2PrivateKeyLocation' not set"]; keyContent = [NSString stringWithContentsOfFile: filename]; if (!keyContent) [NSException raise: NSGenericException @@ -112,14 +131,16 @@ LassoServerInContext (WOContext *context) filename = [sd SAML2CertificateLocation]; if (!filename) [NSException raise: NSInvalidArgumentException - format: @"'SAML2CertificateLocation' not set"]; + format: @"'SOGoSAML2CertificateLocation' not set"]; certContent = [NSString stringWithContentsOfFile: filename]; if (!certContent) [NSException raise: NSGenericException format: @"certificate file '%@' could not be read", filename]; - metadata = [SOGoSAML2Session metadataInContext: context]; + metadata = [SOGoSAML2Session metadataInContext: context + certificate: certContent]; + /* FIXME: enable key password in config ? */ server = lasso_server_new_from_buffers ([metadata UTF8String], [keyContent UTF8String], @@ -148,7 +169,7 @@ LassoServerInContext (WOContext *context) NSString *url; GList *providers; - server = LassoServerInContext (context); + server = [SOGoSAML2Session lassoServerInContext: context]; tempLogin = lasso_login_new (server); providers = g_hash_table_get_keys (server->providers); @@ -181,8 +202,10 @@ LassoServerInContext (WOContext *context) } + (NSString *) metadataInContext: (WOContext *) context + certificate: (NSString *) certificate { - NSString *metadata, *serverURLString, *filename; + NSString *serverURLString, *filename; + NSMutableString *metadata; NSBundle *bundle; bundle = [NSBundle bundleForClass: self]; @@ -190,9 +213,16 @@ LassoServerInContext (WOContext *context) if (filename) { serverURLString = [context SAML2ServerURLString]; - metadata = [[NSString stringWithContentsOfFile: filename] - stringByReplacingString: @"%{base_url}" - withString: serverURLString]; + + metadata = [NSMutableString stringWithContentsOfFile: filename]; + [metadata replaceOccurrencesOfString: @"%{base_url}" + withString: serverURLString + options: 0 + range: NSMakeRange(0, [metadata length])]; + [metadata replaceOccurrencesOfString: @"%{certificate}" + withString: [certificate cleanedUpCertificate] + options: 0 + range: NSMakeRange(0, [metadata length])]; } else metadata = nil; @@ -208,6 +238,8 @@ LassoServerInContext (WOContext *context) login = nil; identifier = nil; assertion = nil; + identity = nil; + session = nil; } return self; @@ -215,7 +247,6 @@ LassoServerInContext (WOContext *context) - (void) _updateDataFromLogin { - // LassoSamlp2Response *response; LassoSaml2Assertion *saml2Assertion; GList *statementList, *attributeList; LassoSaml2AttributeStatement *statement; @@ -223,10 +254,15 @@ LassoServerInContext (WOContext *context) LassoSaml2AttributeValue *value; LassoMiscTextNode *textNode; LassoSaml2NameID *nameIdentifier; + SOGoSystemDefaults *sd; + NSString *loginAttribue; + gchar *dump; - saml2Assertion - = LASSO_SAML2_ASSERTION (lasso_login_get_assertion (lassoLogin)); + saml2Assertion = LASSO_SAML2_ASSERTION (lasso_login_get_assertion (lassoLogin)); + sd = [SOGoSystemDefaults sharedSystemDefaults]; + loginAttribue = [sd SAML2LoginAttribute]; + if (saml2Assertion) { /* deduce user login */ @@ -241,22 +277,42 @@ LassoServerInContext (WOContext *context) while (!login && attributeList) { attribute = LASSO_SAML2_ATTRIBUTE (attributeList->data); - if (strcmp (attribute->Name, "uid") == 0) + if (loginAttribue && (strcmp (attribute->Name, [loginAttribue UTF8String]) == 0)) { value = LASSO_SAML2_ATTRIBUTE_VALUE (attribute->AttributeValue->data); textNode = value->any->data; + + // If we got an @ sign in the value, it's most likely an email address + // so we'll ask SOGoUserManager about this login = [NSString stringWithUTF8String: textNode->content]; + + if ([login rangeOfString: @"@"].location != NSNotFound) + { + login = [[SOGoUserManager sharedUserManager] getUIDForEmail: login]; + } + [login retain]; } - else if (strcmp (attribute->Name, "mail") == 0) + else if (!loginAttribue) { - value = LASSO_SAML2_ATTRIBUTE_VALUE (attribute->AttributeValue->data); - textNode = value->any->data; - login = [[SOGoUserManager sharedUserManager] getUIDForEmail: [NSString stringWithUTF8String: textNode->content]]; - [login retain]; + // We fallback on "standard" attributes such as "uid" and "mail" + if (strcmp (attribute->Name, "uid") == 0) + { + value = LASSO_SAML2_ATTRIBUTE_VALUE (attribute->AttributeValue->data); + textNode = value->any->data; + login = [NSString stringWithUTF8String: textNode->content]; + [login retain]; + } + else if (strcmp (attribute->Name, "mail") == 0) + { + value = LASSO_SAML2_ATTRIBUTE_VALUE (attribute->AttributeValue->data); + textNode = value->any->data; + login = [[SOGoUserManager sharedUserManager] getUIDForEmail: [NSString stringWithUTF8String: textNode->content]]; + [login retain]; + } } - else - attributeList = attributeList->next; + + attributeList = attributeList->next; } statementList = statementList->next; } @@ -295,7 +351,7 @@ LassoServerInContext (WOContext *context) if ((self = [self init])) { - server = LassoServerInContext (context); + server = [SOGoSAML2Session lassoServerInContext: context]; lassoLogin = lasso_login_new (server); if (saml2Dump) { @@ -303,12 +359,17 @@ LassoServerInContext (WOContext *context) ASSIGN (login, [saml2Dump objectForKey: @"login"]); ASSIGN (identifier, [saml2Dump objectForKey: @"identifier"]); ASSIGN (assertion, [saml2Dump objectForKey: @"assertion"]); - dump = [[saml2Dump objectForKey: @"identity"] UTF8String]; + + ASSIGN(identity, [saml2Dump objectForKey: @"identity"]); + dump = [identity UTF8String]; if (dump) lasso_profile_set_identity_from_dump (profile, dump); - dump = [[saml2Dump objectForKey: @"session"] UTF8String]; + + ASSIGN (session, [saml2Dump objectForKey: @"session"]); + dump = [session UTF8String]; if (dump) lasso_profile_set_session_from_dump (profile, dump); + lasso_login_accept_sso (lassoLogin); // if (rc) // [NSException raiseSAML2Exception: rc]; @@ -326,6 +387,9 @@ LassoServerInContext (WOContext *context) [login release]; [identifier release]; [assertion release]; + [identity release]; + [session release]; + [super dealloc]; } @@ -378,13 +442,23 @@ LassoServerInContext (WOContext *context) return assertion; } +- (NSString *) identity +{ + return identity; +} + +- (NSString *) session +{ + return session; +} + - (void) processAuthnResponse: (NSString *) authnResponse { lasso_error_t rc; gchar *responseData, *dump; LassoProfile *profile; - LassoIdentity *identity; - LassoSession *session; + LassoIdentity *lasso_identity; + LassoSession *lasso_session; NSString *nsDump; NSMutableDictionary *saml2Dump; @@ -408,22 +482,22 @@ LassoServerInContext (WOContext *context) profile = LASSO_PROFILE (lassoLogin); - session = lasso_profile_get_session (profile); - if (session) + lasso_session = lasso_profile_get_session (profile); + if (lasso_session) { - dump = lasso_session_dump (session); + dump = lasso_session_dump (lasso_session); nsDump = [NSString stringWithUTF8String: dump]; [saml2Dump setObject: nsDump forKey: @"session"]; - lasso_session_destroy (session); + lasso_session_destroy (lasso_session); } - identity = lasso_profile_get_identity (profile); - if (identity) + lasso_identity = lasso_profile_get_identity (profile); + if (lasso_identity) { - dump = lasso_identity_dump (identity); + dump = lasso_identity_dump (lasso_identity); nsDump = [NSString stringWithUTF8String: dump]; [saml2Dump setObject: nsDump forKey: @"identity"]; - lasso_identity_destroy (identity); + lasso_identity_destroy (lasso_identity); } [[SOGoCache sharedCache] setSaml2LoginDumps: saml2Dump diff --git a/SoObjects/SOGo/SOGoSession.h b/SoObjects/SOGo/SOGoSession.h index 42e2ddd9a..a22b46e94 100644 --- a/SoObjects/SOGo/SOGoSession.h +++ b/SoObjects/SOGo/SOGoSession.h @@ -1,9 +1,6 @@ /* SOGoSession.h - this file is part of SOGo * - * Copyright (C) 2010-2011 Inverse inc. - * - * Author: Ludovic Marcotte - * Francis Lachapelle + * Copyright (C) 2010-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoSession.m b/SoObjects/SOGo/SOGoSession.m index e2137349f..235ef371e 100644 --- a/SoObjects/SOGo/SOGoSession.m +++ b/SoObjects/SOGo/SOGoSession.m @@ -1,10 +1,6 @@ /* SOGoSession.m - this file is part of SOGo * - * Copyright (C) 2010-2011 Inverse inc. - * - * Author: Ludovic Marcotte - * Francis Lachapelle - + * Copyright (C) 2010-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoSieveManager.m b/SoObjects/SOGo/SOGoSieveManager.m index 7c335109f..2f949ad20 100644 --- a/SoObjects/SOGo/SOGoSieveManager.m +++ b/SoObjects/SOGo/SOGoSieveManager.m @@ -1,6 +1,6 @@ /* SOGoSieveManager.m - this file is part of SOGo * - * Copyright (C) 2010-2014 Inverse inc. + * Copyright (C) 2010-2015 Inverse inc. * * Author: Inverse * @@ -31,6 +31,7 @@ #import #import +#import #import #import @@ -717,7 +718,7 @@ static NSString *sieveScriptName = @"sogo"; client = [[NGSieveClient alloc] initWithURL: url]; if (!client) { - NSLog(@"Sieve connection failed on %@", [url description]); + [self errorWithFormat: @"Sieve connection failed on %@", [url description]]; return nil; } @@ -738,19 +739,19 @@ static NSString *sieveScriptName = @"sogo"; if (!connected) { - NSLog(@"Sieve connection failed on %@", [url description]); + [self errorWithFormat: @"Sieve connection failed on %@", [url description]]; return nil; } if (![[result valueForKey:@"result"] boolValue] && !theUsername && !thePassword) { - NSLog(@"failure. Attempting with a renewed password (no authname supported)"); + [self logWithFormat: @"failure. Attempting with a renewed password (no authname supported)"]; password = [theAccount imap4PasswordRenewed: YES]; result = [client login: login password: password]; } if (![[result valueForKey:@"result"] boolValue]) { - NSLog(@"Could not login '%@' on Sieve server: %@: %@", - login, client, result); + [self logWithFormat: @"Could not login '%@' on Sieve server: %@: %@", + login, client, result]; [client closeConnection]; return nil; } @@ -823,7 +824,7 @@ static NSString *sieveScriptName = @"sogo"; } else { - NSLog(@"Sieve generation failure: %@", [self lastScriptError]); + [self errorWithFormat: @"Sieve generation failure: %@", [self lastScriptError]]; [client closeConnection]; return NO; } @@ -913,7 +914,7 @@ static NSString *sieveScriptName = @"sogo"; result = [client deleteScript: sieveScriptName]; if (![[result valueForKey:@"result"] boolValue]) { - NSLog(@"WARNING: Could not delete Sieve script - continuing...: %@", result); + [self logWithFormat: @"WARNING: Could not delete Sieve script - continuing...: %@", result]; } // We put and activate the script only if we actually have a script @@ -923,14 +924,14 @@ static NSString *sieveScriptName = @"sogo"; result = [client putScript: sieveScriptName script: script]; if (![[result valueForKey:@"result"] boolValue]) { - NSLog(@"Could not upload Sieve script: %@", result); + [self logWithFormat: @"Could not upload Sieve script: %@", result]; [client closeConnection]; return NO; } result = [client setActiveScript: sieveScriptName]; if (![[result valueForKey:@"result"] boolValue]) { - NSLog(@"Could not enable Sieve script: %@", result); + [self logWithFormat: @"Could not enable Sieve script: %@", result]; [client closeConnection]; return NO; } diff --git a/SoObjects/SOGo/SOGoSystemDefaults.h b/SoObjects/SOGo/SOGoSystemDefaults.h index bf6032c9b..7f811f208 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.h +++ b/SoObjects/SOGo/SOGoSystemDefaults.h @@ -80,7 +80,9 @@ - (NSString *) SAML2IdpMetadataLocation; - (NSString *) SAML2IdpPublicKeyLocation; - (NSString *) SAML2IdpCertificateLocation; +- (NSString *) SAML2LoginAttribute; - (BOOL) SAML2LogoutEnabled; +- (NSString *) SAML2LogoutURL; - (BOOL) enablePublicAccess; @@ -97,6 +99,7 @@ - (int) maximumSyncInterval; - (int) internalSyncInterval; - (int) maximumSyncWindowSize; +- (int) maximumSyncResponseSize; @end diff --git a/SoObjects/SOGo/SOGoSystemDefaults.m b/SoObjects/SOGo/SOGoSystemDefaults.m index 01150e287..9fbb9ef48 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.m +++ b/SoObjects/SOGo/SOGoSystemDefaults.m @@ -511,6 +511,16 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, return [self boolForKey: @"SOGoSAML2LogoutEnabled"]; } +- (NSString *) SAML2LogoutURL +{ + return [self stringForKey: @"SOGoSAML2LogoutURL"]; +} + +- (NSString *) SAML2LoginAttribute +{ + return [self stringForKey: @"SOGoSAML2LoginAttribute"]; +} + - (BOOL) enablePublicAccess { return [self boolForKey: @"SOGoEnablePublicAccess"]; @@ -592,7 +602,7 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, v = [self integerForKey: @"SOGoMaximumPingInterval"]; if (!v) - v = 5; + v = 10; return v; } @@ -626,4 +636,16 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, return [self integerForKey: @"SOGoMaximumSyncWindowSize"]; } +- (int) maximumSyncResponseSize +{ + int v; + + v = [self integerForKey: @"SOGoMaximumSyncResponseSize"]; + + if (v > 0) + v = v * 1024; + + return v; +} + @end diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index 8f2768571..da0ed8c6c 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2006-2013 Inverse inc. + Copyright (C) 2006-2015 Inverse inc. Copyright (C) 2005 SKYRIX Software AG This file is part of SOGo. diff --git a/SoObjects/SOGo/SOGoUserDefaults.h b/SoObjects/SOGo/SOGoUserDefaults.h index 4cb893b8d..66dbcf5fb 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.h +++ b/SoObjects/SOGo/SOGoUserDefaults.h @@ -1,6 +1,6 @@ /* SOGoUserDefaults.h - this file is part of SOGo * - * Copyright (C) 2011-2013 Inverse inc. + * Copyright (C) 2011-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -126,6 +126,9 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (void) setMailDisplayRemoteInlineImages: (NSString *) newValue; - (NSString *) mailDisplayRemoteInlineImages; +- (void) setMailAutoSave: (NSString *) newValue; +- (NSString *) mailAutoSave; + - (void) setMailMessageForwarding: (NSString *) newValue; - (NSString *) mailMessageForwarding; diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index 031a3283a..5d975f146 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -1,6 +1,6 @@ /* SOGoUserDefaults.m - this file is part of SOGo * - * Copyright (C) 2009-2013 Inverse inc. + * Copyright (C) 2009-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -508,7 +508,7 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return [self stringForKey: @"SOGoMailComposeMessageType"]; } -- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue; +- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue { [self setObject: newValue forKey: @"SOGoMailDisplayRemoteInlineImages"]; } @@ -518,6 +518,23 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return [self stringForKey: @"SOGoMailDisplayRemoteInlineImages"]; } +- (void) setMailAutoSave: (NSString *) newValue +{ + [self setObject: newValue forKey: @"SOGoMailAutoSave"]; +} + +- (NSString *) mailAutoSave +{ + NSString *s; + + s = [self stringForKey: @"SOGoMailAutoSave"]; + + if ([s intValue] == 0) + s = @"5"; + + return s; +} + - (void) setMailMessageForwarding: (NSString *) newValue { [self setObject: newValue forKey: @"SOGoMailMessageForwarding"]; diff --git a/SoObjects/SOGo/SOGoUserFolder.h b/SoObjects/SOGo/SOGoUserFolder.h index 4ee6bdd65..0621728a7 100644 --- a/SoObjects/SOGo/SOGoUserFolder.h +++ b/SoObjects/SOGo/SOGoUserFolder.h @@ -31,7 +31,7 @@ Child objects: 'Calendar': SOGoAppointmentFolder - The SOGoUserFolder is the "home directory" of the user where all his + The SOGoUserFolder is the "home directory" of the user where all their processing starts. It is the 'znek' in such a path: /SOGo/so/znek/Calendar */ diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index 9292f9ffa..ba8414b81 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -153,14 +153,12 @@ - (NSArray *) _subFoldersFromFolder: (SOGoParentFolder *) parentFolder { - NSDictionary *folderSubscriptionValues, *ownerIdentity; - NSString *folderName, *folderOwner, *formattedName; + NSString *folderName, *folderOwner; NSMutableDictionary *currentDictionary; SoSecurityManager *securityManager; SOGoFolder *currentFolder; NSEnumerator *subfolders; NSMutableArray *folders; - SOGoDomainDefaults *dd; Class subfolderClass; folders = [NSMutableArray array]; @@ -193,17 +191,6 @@ [currentDictionary setObject: [currentFolder folderType] forKey: @"type"]; - dd = [[context activeUser] domainDefaults]; - ownerIdentity = [[SOGoUserManager sharedUserManager] - contactInfosForUserWithUIDorEmail: owner]; - folderSubscriptionValues = [[NSDictionary alloc] initWithObjectsAndKeys: [currentFolder displayName], @"FolderName", - [ownerIdentity objectForKey: @"cn"], @"UserName", - [ownerIdentity objectForKey: @"c_email"], @"Email", nil]; - - formattedName = [folderSubscriptionValues keysWithFormat: [dd subscriptionFolderFormat]]; - [currentDictionary setObject: formattedName - forKey: @"formattedName"]; - [folders addObject: currentDictionary]; } } diff --git a/SoObjects/SOGo/SOGoUserManager.h b/SoObjects/SOGo/SOGoUserManager.h index 6564e10b2..237347053 100644 --- a/SoObjects/SOGo/SOGoUserManager.h +++ b/SoObjects/SOGo/SOGoUserManager.h @@ -1,9 +1,6 @@ /* SOGoUserManager.h - this file is part of SOGo * - * Copyright (C) 2007-2013 Inverse inc. - * - * Author: Wolfgang Sourdeau - * Francis Lachapelle + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 03cf78e62..d8e09ba6c 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -1,9 +1,6 @@ /* SOGoUserManager.m - this file is part of SOGo * - * Copyright (C) 2007-2013 Inverse inc. - * - * Author: Wolfgang Sourdeau - * Francis Lachapelle + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoWebAuthenticator.m b/SoObjects/SOGo/SOGoWebAuthenticator.m index 6d6aacad1..bd386d035 100644 --- a/SoObjects/SOGo/SOGoWebAuthenticator.m +++ b/SoObjects/SOGo/SOGoWebAuthenticator.m @@ -1,6 +1,6 @@ /* SOGoWebAuthenticator.m - this file is part of SOGo * - * Copyright (C) 2007-2013 Inverse inc. + * Copyright (C) 2007-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/SOGoWebDAVAclManager.m b/SoObjects/SOGo/SOGoWebDAVAclManager.m index 1c410512a..dcc4210df 100644 --- a/SoObjects/SOGo/SOGoWebDAVAclManager.m +++ b/SoObjects/SOGo/SOGoWebDAVAclManager.m @@ -1,8 +1,6 @@ /* SOGoWebDAVAclManager.m - this file is part of SOGo * - * Copyright (C) 2008 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2008-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/WOContext+SOGo.h b/SoObjects/SOGo/WOContext+SOGo.h index f13bbcd0c..c6d50cd68 100644 --- a/SoObjects/SOGo/WOContext+SOGo.h +++ b/SoObjects/SOGo/WOContext+SOGo.h @@ -1,8 +1,6 @@ /* WOContext+SOGo.h - this file is part of SOGo * - * Copyright (C) 2008 Inverse inc. - * - * Author: Francis Lachapelle + * Copyright (C) 2008-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/WOContext+SOGo.m b/SoObjects/SOGo/WOContext+SOGo.m index e5f992ccf..c558b1be6 100644 --- a/SoObjects/SOGo/WOContext+SOGo.m +++ b/SoObjects/SOGo/WOContext+SOGo.m @@ -1,8 +1,6 @@ /* WOContext+SOGo.m - this file is part of SOGo * - * Copyright (C) 2008 Inverse inc. - * - * Author: Francis Lachapelle + * Copyright (C) 2008-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/WORequest+SOGo.h b/SoObjects/SOGo/WORequest+SOGo.h index f749d183c..9ae6c9104 100644 --- a/SoObjects/SOGo/WORequest+SOGo.h +++ b/SoObjects/SOGo/WORequest+SOGo.h @@ -1,8 +1,6 @@ /* WORequest+SOGo.h - this file is part of SOGo * - * Copyright (C) 2007 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/SoObjects/SOGo/WORequest+SOGo.m b/SoObjects/SOGo/WORequest+SOGo.m index ff3554fd6..f528343dd 100644 --- a/SoObjects/SOGo/WORequest+SOGo.m +++ b/SoObjects/SOGo/WORequest+SOGo.m @@ -1,6 +1,6 @@ /* WORequest+SOGo.m - this file is part of SOGo * - * Copyright (C) 2007-2014 Inverse inc. + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -127,10 +127,14 @@ || [self isAppleDAVWithSubstring: @"iOS/"]; } +// +// Mac+OS+X/10.10.1 (14B25) CalendarAgent/315 +// - (BOOL) isICal { return ([self isAppleDAVWithSubstring: @"Mac OS X/10."] || [self isAppleDAVWithSubstring: @"Mac_OS_X/"] + || [self isAppleDAVWithSubstring: @"Mac+OS+X/"] || [self isAppleDAVWithSubstring: @"CoreDAV/"]); } diff --git a/SoObjects/common.make b/SoObjects/common.make index 31f10e1ac..f2c00d252 100644 --- a/SoObjects/common.make +++ b/SoObjects/common.make @@ -18,17 +18,17 @@ ADDITIONAL_INCLUDE_DIRS += \ -I../../SOPE ADDITIONAL_LIB_DIRS += \ - -L../SOGo/SOGo.framework/ \ + -L../SOGo/SOGo.framework/Versions/Current/sogo/ -lSOGo \ -L../../SOGo/$(GNUSTEP_OBJ_DIR)/ \ - -L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \ - -L/usr/local/lib + -L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ -lNGCards \ + -L../../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/ -lGDLContentStore \ + -L/usr/local/lib \ + -Wl,-rpath,$(SOGO_SYSLIBDIR)/sogo BUNDLE_LIBS += \ - -lSOGo \ - -lGDLContentStore \ -lGDLAccess \ -lNGObjWeb \ - -lNGCards -lNGMime -lNGLdap \ + -lNGMime -lNGLdap \ -lNGStreams -lNGExtensions -lEOControl \ -lDOM -lSaxObjC -lSBJson diff --git a/Tests/Integration/GNUmakefile.preamble b/Tests/Integration/GNUmakefile.preamble index cd29c8e19..68878f481 100644 --- a/Tests/Integration/GNUmakefile.preamble +++ b/Tests/Integration/GNUmakefile.preamble @@ -10,9 +10,10 @@ ADDITIONAL_INCLUDE_DIRS += \ -D_GNU_SOURCE -I../../SOPE/ -I../../SoObjects/ ADDITIONAL_LIB_DIRS += \ - -L../../SoObjects/SOGo/SOGo.framework -lSOGo \ + -L../../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo -lSOGo \ -L../../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/ -lGDLContentStore \ -L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ -lNGCards \ - -L/usr/local/lib -L/usr/lib -lEOControl -lNGStreams -lNGMime -lNGExtensions + -L/usr/local/lib/sogo -L/usr/lib/sogo -L/usr/lib64/sogo -lEOControl -lNGStreams -lNGMime -lNGExtensions -ADDITIONAL_LDFLAGS += -Wl,--no-as-needed + +ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -Wl,--rpath,$(GNUSTEP_SYSTEM_LIBRARIES)/sogo diff --git a/Tests/Integration/test-davacl.py b/Tests/Integration/test-davacl.py index a8a1a5bac..e155966c2 100755 --- a/Tests/Integration/test-davacl.py +++ b/Tests/Integration/test-davacl.py @@ -683,12 +683,12 @@ class DAVCalendarAclTest(DAVAclTest): if right == "r": exp_event = event_template % {"class": icsClass, "filename": filename, - "organizer_line": "ORGANIZER:mailto:nobody@somewhere.com\n", + "organizer_line": "ORGANIZER;CN=nobody@somewhere.com:mailto:nobody@somewhere.com\n", "attendee_line": att_line} else: exp_event = event_template % {"class": icsClass, "filename": filename, - "organizer_line": "ORGANIZER:mailto:someone@nowhere.com\n", + "organizer_line": "ORGANIZER;CN=someone@nowhere.com:mailto:someone@nowhere.com\n", "attendee_line": att_line} event = self._getEvent(event_class, True) ics_diff = utilities.ics_compare(exp_event, event) diff --git a/Tests/Unit/GNUmakefile b/Tests/Unit/GNUmakefile index 6b99e05a5..bcfd13850 100644 --- a/Tests/Unit/GNUmakefile +++ b/Tests/Unit/GNUmakefile @@ -33,9 +33,9 @@ $(TEST_TOOL)_CPPFLAGS += \ -Wall -D_GNU_SOURCE -I../../SOPE/ -I../../SoObjects/ -I../../UI/ ADDITIONAL_LIB_DIRS += \ - -L../../SoObjects/SOGo/SOGo.framework/Versions/Current -L../../SOPE/NGCards/obj -L../../SOPE/GDLContentStore/obj -lSOGo -lNGMime -lNGCards -lGDLContentStore -lNGExtensions -lSBJson -lobjc \ + -L../../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo -L../../SOPE/NGCards/obj -L../../SOPE/GDLContentStore/obj -lSOGo -lNGMime -lNGCards -lGDLContentStore -lNGExtensions -lSBJson -lobjc \ -L/usr/local/lib -lSaxObjC \ - -Wl,-rpath,../../SoObjects/SOGo/SOGo.framework/Versions/Current -Wl,-rpath,../../SOPE/NGCards/obj -Wl,-rpath,../../SOPE/GDLContentStore/obj + -Wl,-rpath,../../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo -Wl,-rpath,../../SOPE/NGCards/obj -Wl,-rpath,../../SOPE/GDLContentStore/obj ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -include GNUmakefile.preamble diff --git a/Tools/GNUmakefile b/Tools/GNUmakefile index c5b56a1fc..869fb52c6 100644 --- a/Tools/GNUmakefile +++ b/Tools/GNUmakefile @@ -4,6 +4,8 @@ include ../config.make include $(GNUSTEP_MAKEFILES)/common.make include ../Version +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo + ### SOGO_TOOL = sogo-tool $(SOGO_TOOL)_INSTALL_DIR = $(SOGO_ADMIN_TOOLS) @@ -20,7 +22,8 @@ $(SOGO_TOOL)_OBJC_FILES += \ SOGoToolRemoveDoubles.m \ SOGoToolRenameUser.m \ SOGoToolRestore.m \ - SOGoToolUserPreferences.m + SOGoToolUserPreferences.m \ + SOGoToolManageEAS.m TOOL_NAME += $(SOGO_TOOL) ### diff --git a/Tools/GNUmakefile.preamble b/Tools/GNUmakefile.preamble index fc78b8b0a..f6ed0bb7f 100644 --- a/Tools/GNUmakefile.preamble +++ b/Tools/GNUmakefile.preamble @@ -10,7 +10,7 @@ ADDITIONAL_INCLUDE_DIRS += \ -D_GNU_SOURCE -I../SOPE/ -I../SoObjects/ ADDITIONAL_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework -lSOGo \ + -L../SoObjects/SOGo/SOGo.framework/sogo -lSOGo \ -L../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/ -lGDLContentStore \ -L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ -lNGCards \ - -L/usr/local/lib -L/usr/lib -lEOControl -lNGStreams -lNGMime -lNGExtensions -lNGObjWeb + -lEOControl -lNGStreams -lNGMime -lNGExtensions -lNGObjWeb diff --git a/Tools/SOGoToolManageEAS.m b/Tools/SOGoToolManageEAS.m new file mode 100644 index 000000000..0d8a7d772 --- /dev/null +++ b/Tools/SOGoToolManageEAS.m @@ -0,0 +1,292 @@ +/* SOGoToolManageEAS.m - this file is part of SOGo + * + * Copyright (C) 2014 Inverse inc. + * + * This file 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; either version 2, or (at your option) + * any later version. + * + * This file 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import +#import +#import +#import +#import +#import + +#import +#import + +#import +#import +#import "SOGo/SOGoCredentialsFile.h" +#import +#import +#import +#import +#import +#import +#import + +#import + + +#import "SOGoTool.h" + +typedef enum +{ + ManageEASUnknown = -1, + ManageEASListDevices = 0, + ManageEASListFolders = 2, + ManageEASResetDevice = 3, + ManageEASRestFolder = 4, +} SOGoManageEASCommand; + +@interface SOGoToolManageEAS : SOGoTool +@end + +@implementation SOGoToolManageEAS + ++ (void) initialize +{ +} + ++ (NSString *) command +{ + return @"manage-eas"; +} + ++ (NSString *) description +{ + return @"manage EAS folders"; +} + +- (void) usage +{ + fprintf (stderr, "manage-eas listdevices|resetdevice|resetfolder user \n\n" + " user the user of whom to reset the whole device or a single folder\n" + " Examples:\n" + " sogo-tool manage-eas listdevices janedoe\n" + " sogo-tool manage-eas listfolders janedoe androidc316986417\n" + " sogo-tool manage-eas resetdevice janedoe androidc316986417\n" + " sogo-tool manage-eas resetfolder janedow androidc316986417+folderlala-dada-sasa_7a13_1a2386e0_e\n") ; +} + + +- (SOGoManageEASCommand) _cmdFromString: (NSString *) theString +{ + if ([theString length] > 2) + { + if ([theString caseInsensitiveCompare: @"listdevices"] == NSOrderedSame) + return ManageEASListDevices; + else if ([theString caseInsensitiveCompare: @"listfolders"] == NSOrderedSame) + return ManageEASListFolders; + else if ([theString caseInsensitiveCompare: @"resetdevice"] == NSOrderedSame) + return ManageEASResetDevice; + else if ([theString caseInsensitiveCompare: @"resetfolder"] == NSOrderedSame) + return ManageEASRestFolder; + } + + return ManageEASUnknown; +} + +- (BOOL) run +{ + NSString *urlString, *deviceId, *userId; + NSMutableString *ocFSTableName; + SOGoCacheGCSObject *oc, *foc; + NSURL *folderTableURL; + NSMutableArray *parts; + NSArray *entries; + id cacheEntry; + + SOGoManageEASCommand cmd; + int i, max; + BOOL rc; + + max = [sanitizedArguments count]; + rc = NO; + + if (max > 1) + { + SOGoUser *user; + + cmd = [self _cmdFromString: [sanitizedArguments objectAtIndex: 0]]; + + userId = [sanitizedArguments objectAtIndex: 1]; + + user = [SOGoUser userWithLogin: userId]; + + if (![user loginInDomain]) + return NO; + + urlString = [[user domainDefaults] folderInfoURL]; + parts = [[urlString componentsSeparatedByString: @"/"] + mutableCopy]; + [parts autorelease]; + if ([parts count] == 5) + { + /* If "OCSFolderInfoURL" is properly configured, we must have 5 + parts in this url. We strip the '-' character in case we have + this in the domain part - like foo@bar-zot.com */ + ocFSTableName = [NSMutableString stringWithFormat: @"sogo_cache_folder_%@", + [[user loginInDomain] asCSSIdentifier]]; + [ocFSTableName replaceOccurrencesOfString: @"-" + withString: @"_" + options: 0 + range: NSMakeRange(0, [ocFSTableName length])]; + [parts replaceObjectAtIndex: 4 withObject: ocFSTableName]; + folderTableURL + = [NSURL URLWithString: [parts componentsJoinedByString: @"/"]]; + [folderTableURL retain]; + } + + switch (cmd) + { + case ManageEASListDevices: + oc = [SOGoCacheGCSObject objectWithName: @"0" inContainer: nil]; + [oc setObjectType: ActiveSyncGlobalCacheObject]; + + [oc setTableUrl: folderTableURL]; + entries = [oc cacheEntriesForDeviceId: nil newerThanVersion: -1]; + + for (i = 0; i < [entries count]; i++) + { + cacheEntry = [entries objectAtIndex: i]; + fprintf(stdout,"%s\n", [[cacheEntry substringFromIndex: 1] UTF8String]); + } + + rc = YES; + break; + + case ManageEASListFolders: + if (max > 2) + { + /* value specified on command line */ + deviceId = [sanitizedArguments objectAtIndex: 2]; + + oc = [SOGoCacheGCSObject objectWithName: @"0" inContainer: nil]; + [oc setObjectType: ActiveSyncFolderCacheObject]; + + [oc setTableUrl: folderTableURL]; + entries = [oc cacheEntriesForDeviceId: deviceId newerThanVersion: -1]; + + for (i = 0; i < [entries count]; i++) + { + cacheEntry = [entries objectAtIndex: i]; + fprintf(stdout,"Folder Key: %s\n", [[cacheEntry substringFromIndex: 1] UTF8String]); + + foc = [SOGoCacheGCSObject objectWithName: [cacheEntry substringFromIndex: 1] inContainer: nil]; + [foc setObjectType: ActiveSyncFolderCacheObject]; + [foc setTableUrl: folderTableURL]; + + [foc reloadIfNeeded]; + + fprintf(stdout, " Folder Name: %s\n\n", [[[foc properties] objectForKey: @"displayName"] UTF8String]); + + if (verbose) + fprintf(stdout, " metadata Name: %s\n\n", [[[foc properties] description] UTF8String]); + } + + rc = YES; + } + else + { + fprintf(stderr, "\nERROR: deviceId not specified\n\n"); + } + + break; + + + case ManageEASResetDevice: + if (max > 2) + { + /* value specified on command line */ + deviceId = [sanitizedArguments objectAtIndex: 2]; + oc = [SOGoCacheGCSObject objectWithName: deviceId inContainer: nil]; + [oc setObjectType: ActiveSyncGlobalCacheObject]; + [oc setTableUrl: folderTableURL]; + + [oc reloadIfNeeded]; + if ([oc isNew]) { + fprintf(stderr, "ERROR: Device with ID '%s' not found\n", [deviceId UTF8String]); + return rc; + } + + NSMutableString *sql; + + sql = [NSMutableString stringWithFormat: @"DELETE FROM %@" @" WHERE c_path like '/%@%'", [oc tableName], deviceId]; + + [oc performBatchSQLQueries: [NSArray arrayWithObject: sql]]; + rc = YES; + } + else + { + fprintf(stderr, "\nERROR: deviceId not specified\n\n"); + } + + break; + + case ManageEASRestFolder: + if (max > 2) + { + /* value specified on command line */ + deviceId = [sanitizedArguments objectAtIndex: 2]; + + //if ([deviceId rangeOfString: @"+"].location == NSNotFound) { + // fprintf(stderr, "ERROR: Deviceid invalid folder \"%@\" not found\n", deviceId); + // return rc; + //} + + oc = [SOGoCacheGCSObject objectWithName: deviceId inContainer: nil]; + [oc setObjectType: ActiveSyncFolderCacheObject]; + [oc setTableUrl: folderTableURL]; + + [oc reloadIfNeeded]; + + if ([oc isNew]) { + fprintf(stderr, "ERROR: Folder with ID \"%s\" not found\n", [deviceId UTF8String]); + return rc; + } + [[oc properties] removeObjectForKey: @"SyncKey"]; + [[oc properties] removeObjectForKey: @"SyncCache"]; + [[oc properties] removeObjectForKey: @"DateCache"]; + [[oc properties] removeObjectForKey: @"MoreAvailable"]; + + [oc save]; + rc = YES; + + } + else + { + fprintf(stderr, "\nERROR: folderId not specified\n\n"); + } + + break; + + case ManageEASUnknown: + break; + } + } + + if (!rc) + { + [self usage]; + } + + return rc; +} + +@end diff --git a/UI/AdministrationUI/GNUmakefile b/UI/AdministrationUI/GNUmakefile index d57aee9dc..041edd709 100644 --- a/UI/AdministrationUI/GNUmakefile +++ b/UI/AdministrationUI/GNUmakefile @@ -25,6 +25,7 @@ AdministrationUI_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/AdministrationUI/SpanishArgentina.lproj/Localizable.strings b/UI/AdministrationUI/SpanishArgentina.lproj/Localizable.strings index 6a13728f5..b10c86a79 100644 --- a/UI/AdministrationUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/AdministrationUI/SpanishArgentina.lproj/Localizable.strings @@ -9,7 +9,7 @@ "ACLs" = "ACL's"; /* Modules titles */ -"ACLs_title" = "Gestión de ALC's para carpetas de usuarios"; +"ACLs_title" = "Gestión de ALC's de las carpetas de usuarios"; /* Modules descriptions */ "ACLs_description" = "

El módulo de administración de Listas de Control de Acceso (ACL) permite cambiar las ACL's del Calendario o de la Libreta de Direcciones de cada usuario

Para modificar las ACL's de la carpeta de un usuario, ingrese el nombre del usuario en el cuadro de búsqueda ubicado en la parte superior de la ventana y haga dobe click en la carpeta deseada.

"; diff --git a/UI/Common/BrazilianPortuguese.lproj/Localizable.strings b/UI/Common/BrazilianPortuguese.lproj/Localizable.strings index 606594535..dabc4b454 100644 --- a/UI/Common/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/Common/BrazilianPortuguese.lproj/Localizable.strings @@ -69,6 +69,7 @@ "You cannot create a list in a shared address book." = "Você não pode criar uma lista em um catálogo público"; "Warning" = "Aviso"; +"Can't contact server" = "Um erro ocorreu na conexão com o servidor. Por favor, tente mais tarde."; "You are not allowed to access this module or this system. Please contact your system administrator." = "Você não está liberado para acessar este módulo ou este sistema. Por favor, contate seu administrador de sistemas."; @@ -87,7 +88,7 @@ "30 minutes" = "30 minutes"; "45 minutes" = "45 minutos"; "1 hour" = "1 hora"; - +"1 day" = "1 dia"; /* common buttons */ "OK" = "OK"; @@ -101,10 +102,9 @@ "Due Date:" = "Data:"; "Location:" = "Localização:"; -/* Mail labels */ +/* mail labels */ "Important" = "Importante"; "Work" = "Trabalho"; -"Work" = "Trabalho"; "Personal" = "Pessoal"; "To Do" = "Tarefa"; "Later" = "Adiar"; diff --git a/UI/Common/GNUmakefile b/UI/Common/GNUmakefile index 5eaf6c036..eb5671695 100644 --- a/UI/Common/GNUmakefile +++ b/UI/Common/GNUmakefile @@ -33,6 +33,7 @@ CommonUI_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/Common/SpanishArgentina.lproj/Localizable.strings b/UI/Common/SpanishArgentina.lproj/Localizable.strings index 11ddb4d91..29f239af2 100644 --- a/UI/Common/SpanishArgentina.lproj/Localizable.strings +++ b/UI/Common/SpanishArgentina.lproj/Localizable.strings @@ -88,7 +88,7 @@ "30 minutes" = "30 minutos"; "45 minutes" = "45 minutos"; "1 hour" = "1 hora"; - +"1 day" = "1 día"; /* common buttons */ "OK" = "OK"; diff --git a/UI/Common/product.plist b/UI/Common/product.plist index 160e4155f..d5d6936a1 100644 --- a/UI/Common/product.plist +++ b/UI/Common/product.plist @@ -107,7 +107,7 @@ actionName = "subscribeUsers"; }; renameFolder = { - protectedBy = "Change Permissions"; + protectedBy = "Access Contents Information"; actionClass = "UIxFolderActions"; actionName = "renameFolder"; }; diff --git a/UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings b/UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings index da9156772..934456c1c 100644 --- a/UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings @@ -36,7 +36,6 @@ "delete" = "apagar"; "edit" = "editar"; "invalidemailwarn" = "O email informado é inválido"; -"invaliddatewarn" = "The specified date is invalid."; "new" = "novo"; "Preferred Phone" = "Telefone Preferencial"; @@ -64,6 +63,7 @@ "New Card" = "Novo Contato"; "New List" = "Nova Lista"; +"Edit" = "Editar"; "Properties" = "Propriedades"; "Sharing..." = "Localizando..."; "Write" = "Escrever"; @@ -147,7 +147,7 @@ "You cannot delete the card of \"%{0}\"." = "Você não pode apagar o contato de \"%{0}\"."; -"Address Book Name" = "Nome do Catálogo"; + "You cannot subscribe to a folder that you own!" = "Você não pode inscrever-se em uma pasta que você é dono."; @@ -206,3 +206,10 @@ "A total of %{0} cards were imported in the addressbook." = "A total of %{0} cards were imported in the addressbook."; "Reload" = "Atualizar"; + +/* Properties window */ +"Address Book Name:" = "Nome do Catálogo:"; +"Links to this Address Book" = "Link para este Catálogo"; +"Authenticated User Access" = "Acesso de Usuário Autenticado"; +"CardDAV URL: " = "CardDAV URL:"; + diff --git a/UI/Contacts/GNUmakefile b/UI/Contacts/GNUmakefile index 6e32c50db..ef8a09ebf 100644 --- a/UI/Contacts/GNUmakefile +++ b/UI/Contacts/GNUmakefile @@ -38,6 +38,7 @@ ContactsUI_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/Contacts/UIxContactView.m b/UI/Contacts/UIxContactView.m index 4880fa667..259a518e9 100644 --- a/UI/Contacts/UIxContactView.m +++ b/UI/Contacts/UIxContactView.m @@ -67,15 +67,18 @@ - (NSString *) _cardStringWithLabel: (NSString *) label value: (NSString *) value + byEscapingHTMLString: (BOOL) escapeHTML asLinkScheme: (NSString *) scheme withLinkAttributes: (NSString *) attrs { NSMutableString *cardString; cardString = [NSMutableString stringWithCapacity: 80]; - value = [[value stringByReplacingString: @"\r" withString: @""] stringByEscapingHTMLString]; + value = [value stringByReplacingString: @"\r" withString: @""]; if ([value length] > 0) { + if (escapeHTML) + value = [value stringByEscapingHTMLString]; if ([scheme length] > 0) value = [NSString stringWithFormat: @"%@", scheme, value, attrs, value]; @@ -94,6 +97,7 @@ { return [self _cardStringWithLabel: label value: value + byEscapingHTMLString: YES asLinkScheme: nil withLinkAttributes: nil]; } @@ -104,6 +108,7 @@ { return [self _cardStringWithLabel: label value: value + byEscapingHTMLString: YES asLinkScheme: scheme withLinkAttributes: nil]; } @@ -144,6 +149,7 @@ return [self _cardStringWithLabel: @"Email:" value: email + byEscapingHTMLString: YES asLinkScheme: @"mailto:" withLinkAttributes: attrs]; } @@ -182,6 +188,7 @@ [secondaryEmails addObject: [self _cardStringWithLabel: nil value: email + byEscapingHTMLString: YES asLinkScheme: @"mailto:" withLinkAttributes: attrs]]; } @@ -365,6 +372,7 @@ return [self _cardStringWithLabel: nil value: data + byEscapingHTMLString: YES asLinkScheme: schema withLinkAttributes: @"target=\"_blank\""]; } @@ -591,13 +599,18 @@ note = [card note]; if (note) { + note = [note stringByEscapingHTMLString]; note = [note stringByReplacingString: @"\r\n" withString: @"
"]; note = [note stringByReplacingString: @"\n" withString: @"
"]; } - return [self _cardStringWithLabel: @"Note:" value: note]; + return [self _cardStringWithLabel: @"Note:" + value: note + byEscapingHTMLString: NO + asLinkScheme: nil + withLinkAttributes: nil]; } /* hrefs */ diff --git a/UI/Contacts/UIxListView.m b/UI/Contacts/UIxListView.m index c4499dfd9..1e3547686 100644 --- a/UI/Contacts/UIxListView.m +++ b/UI/Contacts/UIxListView.m @@ -106,7 +106,7 @@ acquire: NO]; if ([test isKindOfClass: [NSException class]]) { - NSLog (@"%@ not found", [card reference]); + //NSLog (@"%@ not found", [card reference]); cardCopy = [card copy]; [invalid addObject: cardCopy]; [cardCopy release]; diff --git a/UI/MailPartViewers/BrazilianPortuguese.lproj/Localizable.strings b/UI/MailPartViewers/BrazilianPortuguese.lproj/Localizable.strings index 0c23cafd0..d038b316d 100644 --- a/UI/MailPartViewers/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/MailPartViewers/BrazilianPortuguese.lproj/Localizable.strings @@ -12,6 +12,8 @@ publish_info_text = "O solicitante lhe informa sobre um evento anexo."; cancel_info_text = "Seu convite ou evento foi cancelado."; request_info_no_attendee = "está propondo um reunião aos participantes. Você está recebendo este email como uma notificação, você não está agendado como um particiopante."; Appointment = "Apontamento"; +"Status Update" = "Status da Atualização"; +was = "foi"; Organizer = "Organizador"; Time = "Hora"; diff --git a/UI/MailPartViewers/GNUmakefile b/UI/MailPartViewers/GNUmakefile index a094e92eb..57a874fb4 100644 --- a/UI/MailPartViewers/GNUmakefile +++ b/UI/MailPartViewers/GNUmakefile @@ -37,6 +37,7 @@ MailPartViewers_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += $(shell xml2-config --cflags) ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ -L../../SoObjects/Mailer/obj -L../../SoObjects/Appointments/obj +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/MailPartViewers/SpanishArgentina.lproj/Localizable.strings b/UI/MailPartViewers/SpanishArgentina.lproj/Localizable.strings index 1a906cff4..7fa91fcd6 100644 --- a/UI/MailPartViewers/SpanishArgentina.lproj/Localizable.strings +++ b/UI/MailPartViewers/SpanishArgentina.lproj/Localizable.strings @@ -31,7 +31,7 @@ Tentative = "Tentativo"; "delegated from" = "delegado de"; reply_info_no_attendee = "Ha recibido una respuesta a una invitación de evento pero el remitente no aparece como un participante."; -reply_info = "Esta es la respuesta a una invitación a un evento hecha que Usted ha organizado."; +reply_info = "Esta es la respuesta a una invitación a un evento que Usted ha organizado."; "to" = "para"; diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 09d48ae5a..ca41c7f62 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -272,7 +272,7 @@ static NSData* _sanitizeContent(NSData *theData) if ([tag caseInsensitiveCompare: found_tag] == NSOrderedSame) { // Remove the leading slash - NSLog(@"Found void tag with invalid leading slash: ", found_tag); + //NSLog(@"Found void tag with invalid leading slash: ", found_tag); i--; [d replaceBytesInRange: NSMakeRange(i, 1) withBytes: NULL @@ -455,6 +455,10 @@ static NSData* _sanitizeContent(NSData *theData) { if (*currentChar == '{') inCSSDeclaration = YES; + if (*currentChar == '}') + // CSS syntax error: ending declaration character while not in a CSS declaration. + // Ignore eveything from last CSS declaration. + start = currentChar + 1; else if (*currentChar == ',') hasEmbeddedCSS = NO; else if (!hasEmbeddedCSS) diff --git a/UI/MailPartViewers/UIxMailPartICalActions.m b/UI/MailPartViewers/UIxMailPartICalActions.m index be8c47e73..e068ebbe5 100644 --- a/UI/MailPartViewers/UIxMailPartICalActions.m +++ b/UI/MailPartViewers/UIxMailPartICalActions.m @@ -248,6 +248,7 @@ { response = (WOResponse*)[eventObject changeParticipationStatus: newStatus withDelegate: delegate + alarm: nil forRecurrenceId: [chosenEvent recurrenceId]]; // if (ex) // response = ex; //[self responseWithStatus: 500]; diff --git a/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings b/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings index f23eb5b69..b07718473 100644 --- a/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings @@ -13,6 +13,7 @@ "Print" = "Imprimir"; "Stop" = "Parar"; "Write" = "Escrever"; +"Search" = "Pesquisar"; "Send" = "Enviar"; "Contacts" = "Contatos"; @@ -41,6 +42,7 @@ "Attachment" = "Anexos"; "Unread" = "Não Lido"; "Flagged" = "Sinalizado"; +"Search multiple mailboxes" = "Pesquisar múltiplas caixas de correio"; /* Main Frame */ @@ -79,7 +81,7 @@ "Remove this folder" = "Apagar esta pasta"; "Erase mails from this folder" = "Apagar emails desta pasta"; "Expunge this folder" = "Expurgar esta pasta"; -"Archive This Folder" = "Archive This Folder"; +"Export This Folder" = "Exportar esta pasta"; "Modify the acl of this folder" = "Modificar os direitos desta pasta"; "Saved Messages.zip" = "Mensagens Salvas.zip"; @@ -94,14 +96,16 @@ "To" = "Para"; "Cc" = "Cc"; "Bcc" = "Bcc"; -"Reply-To" = "Responder-Para"; +"Reply-To" = "Responder-Para"; "Add address" = "Adicionar endereço"; +"Body" = "Corpo"; -"Attachments:" = "Anexos:"; "Open" = "Abrir"; "Select All" = "Selecionar Tudo"; "Attach Web Page..." = "Anexar Página Web..."; -"Attach File(s)..." = "Anexar Arquivo(s)..."; +"file" = "arquivo"; +"files" = "arquivos"; +"Save all" = "Salvar tudo"; "to" = "Para"; "cc" = "Cc"; @@ -236,6 +240,18 @@ "As Not Junk" = "Como Não é Lixo Eletrônico"; "Run Junk Mail Controls" = "Executar Controle de Lixo Eletrônico"; +"Search messages in:" = "Pesquisar mensagens em:"; +"Search" = "Pesquisar"; +"Search subfolders" = "Pesquisar sub-pastas"; +"Match any of the following" = "Combinar qualquer uma das seguintes"; +"Match all of the following" = "Combinar todas as seguintes"; +"contains" = "contêm"; +"does not contain" = "não contêm"; +"No matches found" = "Nenhuma combinação encontrada"; +"results found" = "Resultados encontrados"; +"result found" = "Resultado encontrado"; +"Please specify at least one filter" = "Por favor, especifique pelo menos um filtro"; + /* Folder operations */ "Name :" = "Nome :"; "Enter the new name of your folder :" @@ -278,6 +294,9 @@ "error_missingsubject" = "Está faltando o Assunto"; "error_missingrecipients" = "Sem destinatários selecionados"; "Send Anyway" = "Enviar assim mesmo"; +"Error while saving the draft:" = "Erro ao salvar o rascunho:"; +"Error while uploading the file \"%{0}\":" = "Erro ao carregar o arquivo \"%{0}\":"; +"There is an active file upload. Closing the window will interrupt it." = "Este arquivo está sendo carregado. Fechando a janela irá interromper o processo."; /* Message sending */ "cannot send message: (smtp) all recipients discarded" = "Não é possível enviar a mensagem: todos os destinatários são inválidos."; diff --git a/UI/MailerUI/GNUmakefile b/UI/MailerUI/GNUmakefile index 851eb9abf..b3754bbaf 100644 --- a/UI/MailerUI/GNUmakefile +++ b/UI/MailerUI/GNUmakefile @@ -46,6 +46,7 @@ MailerUI_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ -L../MailPartViewers/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings b/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings index 101bcfa44..697ab2374 100644 --- a/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/MailerUI/SpanishArgentina.lproj/Localizable.strings @@ -13,6 +13,7 @@ "Print" = "Imprimir"; "Stop" = "Detener"; "Write" = "Redactar"; +"Search" = "Buscar"; "Send" = "Enviar"; "Contacts" = "Contactos"; @@ -41,6 +42,7 @@ "Attachment" = "Adjunto"; "Unread" = "No leído"; "Flagged" = "Marcado"; +"Search multiple mailboxes" = "Buscar en múltiples carpetas"; /* Main Frame */ @@ -94,8 +96,9 @@ "To" = "Para"; "Cc" = "Cc"; "Bcc" = "CCo"; -"Reply-To" = "Responder a"; +"Reply-To" = "Responder a"; "Add address" = "Añadir dirección"; +"Body" = "Cuerpo del mensaje"; "Open" = "Abrir"; "Select All" = "Seleccionar todo"; @@ -237,6 +240,18 @@ "As Not Junk" = "Como correo normal"; "Run Junk Mail Controls" = "Ejecutar controles de correo basura"; +"Search messages in:" = "Buscar mensajes en:"; +"Search" = "Buscar"; +"Search subfolders" = "Buscar en subcarpetas"; +"Match any of the following" = "Coincidir con cualquiera de los siguientes"; +"Match all of the following" = "Coincidir con alguno de los siguientes"; +"contains" = "contiene"; +"does not contain" = "no contiene"; +"No matches found" = "No se encontraron coincidencias"; +"results found" = "resultados encontrados"; +"result found" = "resultado encontrado"; +"Please specify at least one filter" = "Por favor especifique por lo menos un filtro"; + /* Folder operations */ "Name :" = "Nombre: "; "Enter the new name of your folder :" diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m index 5c0a7a661..80c29f512 100644 --- a/UI/MailerUI/UIxMailEditor.m +++ b/UI/MailerUI/UIxMailEditor.m @@ -436,7 +436,7 @@ static NSArray *infoKeys = nil; - (NSDictionary *) storeInfo { [self debugWithFormat:@"storing info ..."]; - return [self valuesForKeys: infoKeys]; + return [self dictionaryWithValuesForKeys: infoKeys]; } /* contacts search */ diff --git a/UI/MailerUI/UIxMailListActions.m b/UI/MailerUI/UIxMailListActions.m index 673de4987..f7c583bfe 100644 --- a/UI/MailerUI/UIxMailListActions.m +++ b/UI/MailerUI/UIxMailListActions.m @@ -394,39 +394,42 @@ NSArray *filters; NSString *searchBy, *searchArgument, *searchInput, *searchString, *match; NSMutableArray *searchArray; - int nbFilters = 0, i; + int nbFilters, i; request = [context request]; content = [[request contentAsString] objectFromJSONString]; qualifier = nil; searchString = nil; + match = nil; + filters = [content objectForKey: @"filters"]; - if ([content objectForKey:@"filters"]) + if (filters) { - filters = [content objectForKey:@"filters"]; - sortingAttributes = [content objectForKey:@"sortingAttributes"]; nbFilters = [filters count]; - match = [NSString stringWithString:[sortingAttributes objectForKey:@"match"]]; // AND, OR - - searchArray = [NSMutableArray arrayWithCapacity:nbFilters]; - for (i = 0; i < nbFilters; i++) - { - searchBy = [NSString stringWithString:[[filters objectAtIndex:i] objectForKey:@"searchBy"]]; - searchArgument = [NSString stringWithString:[[filters objectAtIndex:i] objectForKey:@"searchArgument"]]; - searchInput = [NSString stringWithString:[[filters objectAtIndex:i] objectForKey:@"searchInput"]]; + if (nbFilters > 0) { + searchArray = [NSMutableArray arrayWithCapacity: nbFilters]; + sortingAttributes = [content objectForKey: @"sortingAttributes"]; + if (sortingAttributes) + match = [sortingAttributes objectForKey :@"match"]; // AND, OR + for (i = 0; i < nbFilters; i++) + { + searchBy = [NSString stringWithString: [[filters objectAtIndex:i] objectForKey: @"searchBy"]]; + searchArgument = [NSString stringWithString: [[filters objectAtIndex:i] objectForKey: @"searchArgument"]]; + searchInput = [NSString stringWithString: [[filters objectAtIndex:i] objectForKey: @"searchInput"]]; - if ([[[filters objectAtIndex:i] objectForKey:@"negative"] boolValue]) - searchString = [NSString stringWithFormat:@"(not (%@ %@: '%@'))", searchBy, searchArgument, searchInput]; + if ([[[filters objectAtIndex:i] objectForKey: @"negative"] boolValue]) + searchString = [NSString stringWithFormat: @"(not (%@ %@: '%@'))", searchBy, searchArgument, searchInput]; + else + searchString = [NSString stringWithFormat: @"(%@ %@: '%@')", searchBy, searchArgument, searchInput]; + + searchQualifier = [EOQualifier qualifierWithQualifierFormat: searchString]; + [searchArray addObject: searchQualifier]; + } + if ([match isEqualToString: @"OR"]) + qualifier = [[EOOrQualifier alloc] initWithQualifierArray: searchArray]; else - searchString = [NSString stringWithFormat:@"(%@ %@: '%@')", searchBy, searchArgument, searchInput]; - - searchQualifier = [EOQualifier qualifierWithQualifierFormat:searchString]; - [searchArray addObject:searchQualifier]; - } - if ([match isEqualToString:@"OR"]) - qualifier = [[EOOrQualifier alloc] initWithQualifierArray: searchArray]; - else - qualifier = [[EOAndQualifier alloc] initWithQualifierArray: searchArray]; + qualifier = [[EOAndQualifier alloc] initWithQualifierArray: searchArray]; + } } return qualifier; diff --git a/UI/MailerUI/UIxMailMainFrame.m b/UI/MailerUI/UIxMailMainFrame.m index d94f90aae..488449207 100644 --- a/UI/MailerUI/UIxMailMainFrame.m +++ b/UI/MailerUI/UIxMailMainFrame.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2007-2013 Inverse inc. + Copyright (C) 2007-2014 Inverse inc. This file is part of SOGo. diff --git a/UI/MailerUI/UIxMailSearch.m b/UI/MailerUI/UIxMailSearch.m index a89467df2..92a1ef427 100644 --- a/UI/MailerUI/UIxMailSearch.m +++ b/UI/MailerUI/UIxMailSearch.m @@ -40,26 +40,38 @@ - (void) dealloc { [item release]; + [super dealloc]; } -- (void) setItem: (NSString *) newItem +- (void) setItem: (id) newItem { ASSIGN(item, newItem); } -- (NSString *) item +- (id) item { return item; } +- (NSString *) currentFolderDisplayName +{ + return [[item allValues] lastObject]; +} + +- (NSString *) currentFolderPath +{ + return [[item allKeys] lastObject]; +} + - (NSArray *) mailAccountsList { - SOGoMailAccount *mAccount; + NSDictionary *accountName, *mailbox; + NSString *userName, *aString; SOGoMailAccounts *mAccounts; - NSString *userName, *option, *aString; + SOGoMailAccount *mAccount; NSArray *accountFolders; NSMutableArray *mailboxes; - NSDictionary *accountName; + int nbMailboxes, nbMailAccounts, i, j; // Number of accounts linked with the current user @@ -78,14 +90,17 @@ // Number of mailboxes inside the current account nbMailboxes = [accountFolders count]; - [mailboxes addObject:accountName]; + [mailboxes addObject: [NSDictionary dictionaryWithObject: accountName forKey: accountName]]; + for (j = 0; j < nbMailboxes; j++) { - option = [NSString stringWithFormat:@"%@%@", userName, [[accountFolders objectAtIndex:j] objectForKey:@"displayName"]]; - [mailboxes addObject:option]; + mailbox = [NSDictionary dictionaryWithObject: [NSString stringWithFormat:@"%@%@", userName, [[accountFolders objectAtIndex:j] objectForKey: @"displayName"]] + forKey: [[accountFolders objectAtIndex:j] objectForKey: @"path"]]; + [mailboxes addObject: mailbox]; } } + return mailboxes; } -@end \ No newline at end of file +@end diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index 371a2a504..110fac61b 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -77,7 +77,7 @@ static NSString *mailETag = nil; SOGO_MAJOR_VERSION, SOGO_MINOR_VERSION, SOGO_SUBMINOR_VERSION]; - NSLog (@"Note: using constant etag for mail viewer: '%@'", mailETag); + //NSLog (@"Note: using constant etag for mail viewer: '%@'", mailETag); } - (void) dealloc @@ -315,6 +315,15 @@ static NSString *mailETag = nil; [matchingIdentityEMail retain]; } } + + if (!matchingIdentityEMail) + { + // This can happen if we receive the message because we are + // in the list of bcc. In this case, we take the first + // identity associated with the account. + matchingIdentityEMail = [[[[[self clientObject] mailAccountFolder] identities] lastObject] objectForKey: @"email"]; + RETAIN(matchingIdentityEMail); + } } return matchingIdentityEMail; @@ -487,13 +496,18 @@ static NSString *mailETag = nil; - (NGHashMap *) _receiptMessageHeaderTo: (NSString *) email { + NSString *subject, *from; NGMutableHashMap *map; - NSString *subject; map = [[NGMutableHashMap alloc] initWithCapacity: 1]; [map autorelease]; [map setObject: email forKey: @"to"]; - [map setObject: [self _matchingIdentityEMail] forKey: @"from"]; + + from = [self _matchingIdentityEMail]; + + if (from) + [map setObject: from forKey: @"from"]; + [map setObject: @"multipart/report; report-type=disposition-notification" forKey: @"content-type"]; subject = [NSString stringWithFormat: diff --git a/UI/MainUI/GNUmakefile b/UI/MainUI/GNUmakefile index 62837f307..acd40f8ef 100644 --- a/UI/MainUI/GNUmakefile +++ b/UI/MainUI/GNUmakefile @@ -32,6 +32,7 @@ MainUI_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/MainUI/SOGoMicrosoftActiveSyncActions.m b/UI/MainUI/SOGoMicrosoftActiveSyncActions.m index a00344fba..c487d5cce 100644 --- a/UI/MainUI/SOGoMicrosoftActiveSyncActions.m +++ b/UI/MainUI/SOGoMicrosoftActiveSyncActions.m @@ -21,6 +21,8 @@ #import +#import +#import #import #import @@ -54,13 +56,17 @@ ex = [dispatcher dispatchRequest: request inResponse: response context: context]; + //[[self class] memoryStatistics]; + if (ex) { return [NSException exceptionWithHTTPStatus: 500]; } RELEASE(dispatcher); - + + [[SOGoCache sharedCache] killCache]; + return response; } diff --git a/UI/MainUI/SOGoRootPage.m b/UI/MainUI/SOGoRootPage.m index d8e32c1db..df3e944b1 100644 --- a/UI/MainUI/SOGoRootPage.m +++ b/UI/MainUI/SOGoRootPage.m @@ -361,7 +361,7 @@ if (login) { - /* We redirect the user to his "homepage" when newLocation could not be + /* We redirect the user to their "homepage" when newLocation could not be deduced from the "cas-location" cookie and the current action is not a login callback (ticket != nil). */ if (!newLocation || !ticket) diff --git a/UI/MainUI/SOGoSAML2Actions.m b/UI/MainUI/SOGoSAML2Actions.m index 53ab5d1db..09bc3d060 100644 --- a/UI/MainUI/SOGoSAML2Actions.m +++ b/UI/MainUI/SOGoSAML2Actions.m @@ -32,7 +32,10 @@ #import #import +#import #import +#import +#import #import @interface SOGoSAML2Actions : WODirectAction @@ -42,20 +45,100 @@ - (WOResponse *) saml2MetadataAction { + NSString *metadata, *certContent; + SOGoSystemDefaults *sd; WOResponse *response; - NSString *metadata; response = [context response]; [response setHeader: @"application/xml; charset=utf-8" forKey: @"content-type"]; - metadata = [SOGoSAML2Session metadataInContext: context]; + sd = [SOGoSystemDefaults sharedSystemDefaults]; + + certContent = [NSString stringWithContentsOfFile: [sd SAML2CertificateLocation]]; + + metadata = [SOGoSAML2Session metadataInContext: context + certificate: certContent]; + [response setContentEncoding: NSUTF8StringEncoding]; [response appendContentString: metadata]; return response; } +// +// +// +- (WOResponse *) saml2SingleLogoutServiceAction +{ + NSString *userName, *value, *cookieName, *domain, *username, *password; + SOGoWebAuthenticator *auth; + SOGoSystemDefaults *sd; + WOResponse *response; + NSCalendarDate *date; + WOCookie *cookie; + NSArray *creds; + + userName = [[context activeUser] login]; + [self logWithFormat: @"SAML2 IdP-initiated SLO for user '%@'", userName]; + + sd = [SOGoSystemDefaults sharedSystemDefaults]; + + response = [context response]; + + if ([sd SAML2LogoutURL]) + { + [response setStatus: 302]; + [response setHeader: [sd SAML2LogoutURL] forKey: @"location"]; + } + + if ([userName isEqualToString: @"anonymous"]) + return response; + + cookie = nil; + + date = [NSCalendarDate calendarDate]; + [date setTimeZone: [NSTimeZone timeZoneWithAbbreviation: @"GMT"]]; + + // We cleanup the memecached/database session cache. We do this before + // invoking _logoutCookieWithDate: in order to obtain its value. + auth = [[SoApplication application] authenticatorInContext: context]; + + if ([auth respondsToSelector: @selector (cookieNameInContext:)]) + { + cookieName = [auth cookieNameInContext: context]; + value = [[context request] cookieValueForKey: cookieName]; + creds = [auth parseCredentials: value]; + + // We first delete our memcached entry + value = [SOGoSession valueForSessionKey: [creds lastObject]]; + domain = nil; + + [SOGoSession decodeValue: value + usingKey: [creds objectAtIndex: 0] + login: &username + domain: &domain + password: &password]; + + [[SOGoCache sharedCache] removeSAML2LoginDumpsForIdentifier: password]; + + if ([creds count] > 1) + [SOGoSession deleteValueForSessionKey: [creds objectAtIndex: 1]]; + + if ([cookieName length]) + { + cookie = [WOCookie cookieWithName: cookieName value: @"discard"]; + [cookie setPath: [NSString stringWithFormat: @"/%@/", [[context request] applicationName]]]; + [cookie setExpires: [date yesterday]]; + } + } + + if (cookie) + [response addCookie: cookie]; + + return response; +} + - (WOCookie *) _authLocationResetCookieWithName: (NSString *) cookieName { WOCookie *locationCookie; diff --git a/UI/MainUI/SOGoUserHomePage.m b/UI/MainUI/SOGoUserHomePage.m index 39d96ec26..2a8415d70 100644 --- a/UI/MainUI/SOGoUserHomePage.m +++ b/UI/MainUI/SOGoUserHomePage.m @@ -1,6 +1,6 @@ /* SOGoUserHomePage.m - this file is part of SOGo * - * Copyright (C) 2007-2014 Inverse inc. + * Copyright (C) 2007-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,12 @@ #import #import + +#import #import +#if defined(SAML2_CONFIG) +#import +#endif #import #import #import @@ -98,8 +103,8 @@ maxBookings = [user numberOfSimultaneousBookings]; isResource = [user isResource]; - // Don't fetch freebusy information if the user is of type 'resource' and has unlimited bookings - if (!isResource || maxBookings > 0) + // Fetch freebusy information if the user is NOT a resource or if multiplebookings isn't unlimited + if (!isResource || maxBookings != 0) { for (recordCount = 0; recordCount < recordMax; recordCount++) { @@ -162,10 +167,10 @@ endInterval += (delta/60/15); // Update bit string representation - // If the user is a resource, keep the sum of overlapping events + // If the user is a resource with restristed amount of bookings, keep the sum of overlapping events for (count = startInterval; count < endInterval; count++) { - *(items + count) = isResource ? *(items + count) + 1 : 1; + *(items + count) = (isResource && maxBookings > 0) ? *(items + count) + 1 : 1; } } } @@ -184,6 +189,9 @@ } } +// +// +// - (NSString *) _freeBusyFromStartDate: (NSCalendarDate *) startDate toEndDate: (NSCalendarDate *) endDate forFreeBusy: (SOGoFreeBusyObject *) fb @@ -215,19 +223,23 @@ timeZone: [endDate timeZone]]; interval = [endDate timeIntervalSinceDate: startDate] + 60; - intervals = interval / intervalSeconds; /* slices of 15 minutes */ + + // Slices of 15 minutes. The +8 is to take into account that we can + // have a timezone change during the freebusy lookup. We have +4 at the + // beginning and +4 at the end. + intervals = interval / intervalSeconds + 8; // Build a bit string representation of the freebusy data for the period freeBusyItems = NSZoneCalloc (NULL, intervals, sizeof (int)); - [self _fillFreeBusyItems: freeBusyItems - count: intervals + [self _fillFreeBusyItems: (freeBusyItems+4) + count: (intervals-4) withRecords: [fb fetchFreeBusyInfosFrom: start to: end forContact: uid] fromStartDate: startDate toEndDate: endDate]; - // Convert bit string to a NSArray + // Convert bit string to a NSArray. We also skip by the default the non-requested information. freeBusy = [NSMutableArray arrayWithCapacity: intervals]; - for (count = 0; count < intervals; count++) + for (count = 4; count < (intervals-4); count++) { [freeBusy addObject: [NSString stringWithFormat: @"%d", *(freeBusyItems + count)]]; } @@ -296,14 +308,57 @@ sd = [SOGoSystemDefaults sharedSystemDefaults]; if ([[sd authenticationType] isEqualToString: @"cas"]) - redirectURL = [SOGoCASSession CASURLWithAction: @"logout" - andParameters: nil]; + { + redirectURL = [SOGoCASSession CASURLWithAction: @"logout" + andParameters: nil]; + } +#if defined(SAML2_CONFIG) + else if ([[sd authenticationType] isEqualToString: @"saml2"]) + { + NSString *username, *password, *domain, *value; + SOGoSAML2Session *saml2Session; + SOGoWebAuthenticator *auth; + LassoServer *server; + LassoLogout *logout; + NSArray *creds; + + auth = [[self clientObject] authenticatorInContext: context]; + value = [[context request] cookieValueForKey: [auth cookieNameInContext: context]]; + creds = [auth parseCredentials: value]; + + value = [SOGoSession valueForSessionKey: [creds lastObject]]; + + domain = nil; + + [SOGoSession decodeValue: value + usingKey: [creds objectAtIndex: 0] + login: &username + domain: &domain + password: &password]; + + saml2Session = [SOGoSAML2Session SAML2SessionWithIdentifier: password + inContext: context]; + + server = [SOGoSAML2Session lassoServerInContext: context]; + + logout = lasso_logout_new(server); + + lasso_profile_set_session_from_dump(LASSO_PROFILE(logout), [[saml2Session session] UTF8String]); + lasso_profile_set_identity_from_dump(LASSO_PROFILE(logout), [[saml2Session session] UTF8String]); + lasso_logout_init_request(logout, NULL, LASSO_HTTP_METHOD_REDIRECT); + lasso_logout_build_request_msg(logout); + redirectURL = [NSString stringWithFormat: @"%s", LASSO_PROFILE(logout)->msg_url]; + + // We destroy our cache entry, the session will be taken care by the caller + [[SOGoCache sharedCache] removeSAML2LoginDumpsForIdentifier: password]; + } +#endif else { container = [[self clientObject] container]; redirectURL = [container baseURLInContext: context]; } - + return redirectURL; } diff --git a/UI/MainUI/SpanishArgentina.lproj/Localizable.strings b/UI/MainUI/SpanishArgentina.lproj/Localizable.strings index 99f0cdbee..cd3c336be 100644 --- a/UI/MainUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/MainUI/SpanishArgentina.lproj/Localizable.strings @@ -10,9 +10,9 @@ "Connect" = "Conectar"; "Wrong username or password." = "Nombre de usuario o contraseña incorrectos."; -"cookiesNotEnabled" = "No se puede conectar dado que su navegador no acepta cookies. Por favor, habilite las cookies en la configuración de su navegador y pruebe de nuevo."; +"cookiesNotEnabled" = "No se puede conectar debido a que su navegador no acepta cookies. Por favor, habilite las cookies en la configuración de su navegador y pruebe de nuevo."; -"browserNotCompatible" = "Hemos detectado que éste sistema no soporta su versión del navegador. Recomendamos usar Firefox. Haga click en el siguiente enlace para descargar la versión más reciente de este navegador."; +"browserNotCompatible" = "Hemos detectado que éste sistema no soporta la versión de su navegador. Recomendamos usar Firefox. Haga click en el siguiente enlace para descargar la versión más reciente de este navegador."; "alternativeBrowsers" = "Como alternativa, también puede usar uno se los siguientes navegadores compatibles: "; "alternativeBrowserSafari" = "Como alternativa, puede usar Safari."; "Download" = "Descarga"; @@ -44,7 +44,7 @@ "Welsh" = "Cymraeg"; "About" = "Acerca de"; -"AboutBox" = "Desarrollado por Inverse, SOGo es un servidor groupware (software colaborativo) con todas las características necesarias con un focus para simlicidad y capacidad de ampliación.

\nSOGo facilita una interface web rica basada en AJAX Web y soporta una multitud de clientes a través del soporte de protocolos estándares como CalDAV y CardDAV.

\nSOGo esta distribuido bajo GNU GPL versión 2 o siguiente, y partes bajo la licencia GNU LGPL versión 2. Esto es software libre: esta autorizado el cambio y la redistribución del mismo. No hay garantías, dentro del límite de la ley.

\nVer esta página para las diferentes opciones de soporte."; +"AboutBox" = "SOGo, una herramienta desarrollada por Inverse, es un servidor con múltiples funcionalidades para facilitar el trabajo en grupo. El enfoque de SOGo es la sencillez y la escalabilidad.

\nSOGo provee una potente interfaz Web basada en AJAX y soporta una amplia variedad de clientes nativos mediante el uso de protocólos estándar como CalDAV y CarDAV.

\nSOGO se distribuye bajo la licencia GNU GPL versión 2 o superior. Algunas partes se distribuyen bajo la licencia GNU LGPL version 2. SOGo es software libre: Usted es libre de modificarlo y redistribuirlo. SOGo se distribuye SIN NINGUNA GARANTIA según los alcances permitidos por la ley.

\nConsulte esta página para conocer varias opciones de soporte."; "Your account was locked due to too many failed attempts." = "Su cuenta ha sido bloqueada debido a un número excesivo de errores de conexión."; "Your account was locked due to an expired password." = "Su cuenta ha sido bloqueada debido a una contraseña caducada."; diff --git a/UI/MainUI/product.plist b/UI/MainUI/product.plist index e5c9d2ec1..c9e230177 100644 --- a/UI/MainUI/product.plist +++ b/UI/MainUI/product.plist @@ -133,6 +133,11 @@ actionClass = "SOGoSAML2Actions"; actionName = "saml2SignOnPOST"; }; + saml2-sls = { + protectedBy = ""; + actionClass = "SOGoSAML2Actions"; + actionName = "saml2SingleLogoutService"; + }; /* saml2-signon-redirect = { protectedBy = ""; actionClass = "SOGoSAML2Actions"; diff --git a/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings b/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings index eae77b19b..01dc12d01 100644 --- a/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Encaminhar"; "Password" = "Senha"; "Categories" = "Categorias"; +"Appointments invitations" = "Convites de Compromissos"; "Name" = "Nome"; "Color" = "Cor"; "Add" = "Adicionar"; @@ -97,44 +98,43 @@ "Show time as busy outside working hours" = "Exibir horas como ocupadas quando fora do horário de serviço"; "First week of year :" = "Primeira semana do ano :"; "Enable reminders for Calendar items" = "Habilitar lembretes para os itens do Calendário"; -"Play a sound when a reminder comes due" -= "Executar um som quando existir um lembrete"; +"Play a sound when a reminder comes due" = "Executar um som quando existir um lembrete"; "Default reminder :" = "Lembrete padrão :"; "firstWeekOfYear_January1" = "Inicia em 01 de janeiro"; "firstWeekOfYear_First4DayWeek" = "Primeira semana com 4 dias"; "firstWeekOfYear_FirstFullWeek" = "Primeira semana com 5 dias"; +"Prevent from being invited to appointments" = "Impedir de ser convidado para um compromisso"; +"White list for appointment invitations:" = "Lista branca para convites de compromissos:"; +"Contacts Names" = "Nomes de Contatos"; + /* Default Calendar */ "Default calendar :" = "Calendário Padrão"; "selectedCalendar" = "Calendário selecionado"; "personalCalendar" = "Calendário pessoal"; "firstCalendar" = "Calendário habilizado pela primeira vez"; +"reminder_NONE" = "Não lembrar"; "reminder_5_MINUTES_BEFORE" = "5 minutos"; "reminder_10_MINUTES_BEFORE" = "10 minutos"; "reminder_15_MINUTES_BEFORE" = "15 minutos"; "reminder_30_MINUTES_BEFORE" = "30 minutos"; +"reminder_45_MINUTES_BEFORE" = "45 minutos antes"; "reminder_1_HOUR_BEFORE" = "1 hora"; "reminder_2_HOURS_BEFORE" = "2 horas"; -"reminder_5_HOURS_BEFORE"= "5 horas"; -"reminder_15_HOURS_BEFORE"= "15 horas"; +"reminder_5_HOURS_BEFORE" = "5 horas"; +"reminder_15_HOURS_BEFORE" = "15 horas"; "reminder_1_DAY_BEFORE" = "1 dia"; "reminder_2_DAYS_BEFORE" = "2 dias"; +"reminder_1_WEEK_BEFORE" = "1 semana antes"; /* Mailer */ +"Labels" = "Etiquetas"; "Label" = "Etiqueta"; "Show subscribed mailboxes only" = "Exibir somente caixas de correio inscritas"; "Sort messages by threads" = "Ordenar mensagens por tópicos"; -"Check for new mail:" = "Checar novos emails:"; -"refreshview_manually" = "Manualmente"; -"refreshview_every_minute" = "A cada minuto"; -"refreshview_every_2_minutes" = "A cada 2 minutos"; -"refreshview_every_5_minutes" = "A cada 5 minutos"; -"refreshview_every_10_minutes" = "A cada 10 minutos"; -"refreshview_every_20_minutes" = "A cada 20 minutos"; -"refreshview_every_30_minutes" = "A cada 30 minutos"; -"refreshview_once_per_hour" = "Uma vez por hora"; +"When sending mail, add unknown recipients to my" = "Ao enviar e-mail, adicionar destinatários desconhecidos ao meu"; "Forward messages:" = "Encaminhar mensagens:"; "messageforward_inline" = "No corpo da mensagem"; @@ -153,6 +153,13 @@ "displayremoteinlineimages_never" = "Nunca"; "displayremoteinlineimages_always" = "Sempre"; +"Auto save every" = "Auto salvar cada"; +"minutes" = "minutos"; + +/* Contact */ +"Personal Address Book" = "Catálogo Pessoal"; +"Collected Address Book" = "Catálogo Coletado"; + /* IMAP Accounts */ "New Mail Account" = "Nova conta de e-mail"; @@ -200,6 +207,7 @@ "Mail" = "Correio"; "Last" = "Último usado"; "Default Module :" = "Módulo Padrão:"; +"SOGo Version :" = "Versão SOGo:"; "Language :" = "Idioma :"; "choose" = "Escolha ..."; @@ -227,6 +235,16 @@ "Ukrainian" = "Українська"; "Welsh" = "Cymraeg"; +"Refresh View :" = "Atualizar a Visualização:"; +"refreshview_manually" = "Manualmente"; +"refreshview_every_minute" = "A cada minuto"; +"refreshview_every_2_minutes" = "A cada 2 minutos"; +"refreshview_every_5_minutes" = "A cada 5 minutos"; +"refreshview_every_10_minutes" = "A cada 10 minutos"; +"refreshview_every_20_minutes" = "A cada 20 minutos"; +"refreshview_every_30_minutes" = "A cada 30 minutos"; +"refreshview_once_per_hour" = "Uma vez por hora"; + /* Return receipts */ "When I receive a request for a return receipt:" = "Quando eu receber uma confirmação de leitura:"; "Never send a return receipt" = "Nunca enviar confirmação"; @@ -244,6 +262,8 @@ "Active" = "Ativo"; "Move Up" = "Mover para cima"; "Move Down" = "Move para baixo"; +"Connection error" = "Erro de conexão"; +"Service temporarily unavailable" = "Serviço temporariamente indisponível"; /* Filters - UIxFilterEditor */ "Filter name:" = "Nome do filtro:"; @@ -261,6 +281,7 @@ "To or Cc" = "Para ou Cc"; "Size (Kb)" = "Tamanho (Kb)"; "Header" = "Cabeçalho"; +"Body" = "Corpo"; "Flag the message with:" = "Marcar a mensagem com:"; "Discard the message" = "Discate a mensagem"; "File the message in:" = "Arquivo da mensagem em:"; @@ -287,12 +308,8 @@ "Flagged" = "Marcado"; "Junk" = "Lixo"; "Not Junk" = "Não é Lixo"; -"Label 1" = "Rótulo 1"; -"Label 2" = "Rótulo 2"; -"Label 3" = "Rótulo 3"; -"Label 4" = "Rótulo 4"; -"Label 5" = "Rótulo 5"; +/* Password policy */ "The password was changed successfully." = "Senha alterada com sucesso."; "Password must not be empty." = "Le mot de passe ne doit pas être vide."; "The passwords do not match. Please try again." = "Les mots de passe ne sont pas identiques. Essayez de nouveau."; diff --git a/UI/PreferencesUI/Czech.lproj/Localizable.strings b/UI/PreferencesUI/Czech.lproj/Localizable.strings index 2d36eb27a..891be5277 100644 --- a/UI/PreferencesUI/Czech.lproj/Localizable.strings +++ b/UI/PreferencesUI/Czech.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Přeposílání"; "Password" = "Heslo"; "Categories" = "Kategorie"; +"Appointments invitations" = "Pozvání na schůzky"; "Name" = "Jméno"; "Color" = "Barva"; "Add" = "Přidat"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Nikdy"; "displayremoteinlineimages_always" = "Vždy"; +"Auto save every" = "Automaticky uložit každých"; +"minutes" = "minut"; + /* Contact */ "Personal Address Book" = "Osobní kontakty"; "Collected Address Book" = "Sebrané kontakty"; diff --git a/UI/PreferencesUI/Dutch.lproj/Localizable.strings b/UI/PreferencesUI/Dutch.lproj/Localizable.strings index 38d208cfe..f4fe086f4 100644 --- a/UI/PreferencesUI/Dutch.lproj/Localizable.strings +++ b/UI/PreferencesUI/Dutch.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Doorsturen"; "Password" = "Wachtwoord"; "Categories" = "Categorieën"; +"Appointments invitations" = "Uitnodigingen voor afspraken"; "Name" = "Naam"; "Color" = "Kleur"; "Add" = "Toevoegen"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Nooit"; "displayremoteinlineimages_always" = "Altijd"; +"Auto save every" = "Automatisch opslaan elke"; +"minutes" = "minuten"; + /* Contact */ "Personal Address Book" = "Persoonlijk adresboek"; "Collected Address Book" = "Verzameld adresboek"; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index 65219eec9..538bd3d9b 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Forward"; "Password" = "Password"; "Categories" = "Categories"; +"Appointments invitations" = "Appointments invitations"; "Name" = "Name"; "Color" = "Color"; "Add" = "Add"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Never"; "displayremoteinlineimages_always" = "Always"; +"Auto save every" = "Auto save every"; +"minutes" = "minutes"; + /* Contact */ "Personal Address Book" = "Personal Address Book"; "Collected Address Book" = "Collected Address Book"; diff --git a/UI/PreferencesUI/Finnish.lproj/Localizable.strings b/UI/PreferencesUI/Finnish.lproj/Localizable.strings index 0b4525532..3df3e7718 100644 --- a/UI/PreferencesUI/Finnish.lproj/Localizable.strings +++ b/UI/PreferencesUI/Finnish.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Edelleenlähetys"; "Password" = "Salasana"; "Categories" = "Luokat"; +"Appointments invitations" = "Kalenterikutsut"; "Name" = "Nimi"; "Color" = "Väri"; "Add" = "Lisää"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Ei koskaan"; "displayremoteinlineimages_always" = "Aina"; +"Auto save every" = "Tallenna automaattisesti"; +"minutes" = "minuutin välein"; + /* Contact */ "Personal Address Book" = "Henkilökohtainen osoitekirja"; "Collected Address Book" = "Keratty osoitekirja"; diff --git a/UI/PreferencesUI/French.lproj/Localizable.strings b/UI/PreferencesUI/French.lproj/Localizable.strings index 58218f0e6..4caec8c78 100644 --- a/UI/PreferencesUI/French.lproj/Localizable.strings +++ b/UI/PreferencesUI/French.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Transfert"; "Password" = "Mot de passe"; "Categories" = "Catégories"; +"Appointments invitations" = "Invitations"; "Name" = "Nom"; "Color" = "Couleur"; "Add" = "Ajouter"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Jamais"; "displayremoteinlineimages_always" = "Toujours"; +"Auto save every" = "Sauvegarde automatique toutes les"; +"minutes" = "minutes"; + /* Contact */ "Personal Address Book" = "Adresses personnelles"; "Collected Address Book" = "Adresses collectées"; diff --git a/UI/PreferencesUI/GNUmakefile b/UI/PreferencesUI/GNUmakefile index 7aa0511d2..c2c75ab39 100644 --- a/UI/PreferencesUI/GNUmakefile +++ b/UI/PreferencesUI/GNUmakefile @@ -28,6 +28,7 @@ PreferencesUI_LOCALIZED_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/PreferencesUI/German.lproj/Localizable.strings b/UI/PreferencesUI/German.lproj/Localizable.strings index 050f7c3a5..9b66de389 100644 --- a/UI/PreferencesUI/German.lproj/Localizable.strings +++ b/UI/PreferencesUI/German.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Weiterleitung"; "Password" = "Passwort"; "Categories" = "Kategorien"; +"Appointments invitations" = "Einladungen zu Terminen"; "Name" = "Name"; "Color" = "Farbe"; "Add" = "Hinzufügen"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Niemals"; "displayremoteinlineimages_always" = "Immer"; +"Auto save every" = "Automatisch speichern alle"; +"minutes" = "Minuten"; + /* Contact */ "Personal Address Book" = "Persönliches Adressbuch"; "Collected Address Book" = "Gesammelte Adressen"; diff --git a/UI/PreferencesUI/Hungarian.lproj/Localizable.strings b/UI/PreferencesUI/Hungarian.lproj/Localizable.strings index 97c5be583..9532bf3b3 100644 --- a/UI/PreferencesUI/Hungarian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Hungarian.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Továbbítás"; "Password" = "Jelszó"; "Categories" = "Kategóriák"; +"Appointments invitations" = "Találkozó meghívók"; "Name" = "Név"; "Color" = "Szín"; "Add" = "Hozzáadás"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Soha"; "displayremoteinlineimages_always" = "Mindig"; +"Auto save every" = "Automatikus mentés gyakorisága"; +"minutes" = "perc"; + /* Contact */ "Personal Address Book" = "Személyes címjegyzék"; "Collected Address Book" = "Összegyűjtöt címek jegyzéke"; diff --git a/UI/PreferencesUI/Polish.lproj/Localizable.strings b/UI/PreferencesUI/Polish.lproj/Localizable.strings index df1126f96..9936e5a4c 100644 --- a/UI/PreferencesUI/Polish.lproj/Localizable.strings +++ b/UI/PreferencesUI/Polish.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Przekazywanie"; "Password" = "Hasło"; "Categories" = "Kategorie"; +"Appointments invitations" = "Ograniczanie zaproszeń"; "Name" = "Nazwa"; "Color" = "Kolor"; "Add" = "Dodaj"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Nigdy"; "displayremoteinlineimages_always" = "Zawsze"; +"Auto save every" = "Zapisuj automatycznie co"; +"minutes" = "min."; + /* Contact */ "Personal Address Book" = "Osobista książka adresowa"; "Collected Address Book" = "Książka zebranych adresów"; diff --git a/UI/PreferencesUI/Russian.lproj/Localizable.strings b/UI/PreferencesUI/Russian.lproj/Localizable.strings index 493e39f58..0dc61be59 100644 --- a/UI/PreferencesUI/Russian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Russian.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Переслать"; "Password" = "Пароль"; "Categories" = "Категории"; +"Appointments invitations" = "Цель приглашения"; "Name" = "Имя"; "Color" = "Цвет"; "Add" = "Добавить"; @@ -90,10 +91,10 @@ "timeFmt_4" = ""; /* calendar */ -"Week begins on :" = "Неделя начинается с :"; -"Day start time :" = "Рабочий день начинается в :"; +"Week begins on :" = "Неделя начинается с:"; +"Day start time :" = "Рабочий день начинается в:"; "Day end time :" = "Рабочий день заканчивается в :"; -"Day start time must be prior to day end time." = "Day start time must be prior to day end time."; +"Day start time must be prior to day end time." = "Время начала дня должно быть перед временем его окончания."; "Show time as busy outside working hours" = "Показывать время, как занятое, если оно за границами рабочего времени."; "First week of year :" = "Первая неделя года :"; "Enable reminders for Calendar items" = "Включить напоминания для событий календаря"; @@ -124,8 +125,8 @@ "reminder_2_HOURS_BEFORE" = "2 часа"; "reminder_5_HOURS_BEFORE" = "5 часа"; "reminder_15_HOURS_BEFORE" = "15 часов"; -"reminder_1_DAY_BEFORE" = "1 день"; -"reminder_2_DAYS_BEFORE" = "2 дня"; +"reminder_1_DAY_BEFORE" = "1 день назад"; +"reminder_2_DAYS_BEFORE" = "2 дня назад"; "reminder_1_WEEK_BEFORE" = "За 1 неделю"; /* Mailer */ @@ -145,7 +146,7 @@ "And place my signature" = "И поместить мою подпись"; "signatureplacement_above" = "под ответом"; "signatureplacement_below" = "под цитируемым текстом письма"; -"Compose messages in" = "Compose messages in"; +"Compose messages in" = "Составлять сообщения в"; "composemessagestype_html" = "HTML"; "composemessagestype_text" = "Plain text"; "Display remote inline images" = "Показать встроенные изображения из сети"; @@ -159,11 +160,11 @@ /* IMAP Accounts */ "New Mail Account" = "New Mail Account"; -"Server Name:" = "Server Name:"; -"Port:" = "Port:"; +"Server Name:" = "Имя сервера:"; +"Port:" = "Порт:"; "Encryption:" = "Шифрование:"; "None" = "Нет"; -"User Name:" = "User Name:"; +"User Name:" = "Имя пользователя:"; "Password:" = "Пароль:"; "Full Name:" = "Full Name:"; @@ -173,7 +174,7 @@ "(Click to create)" = "(Click to create)"; "Signature" = "Подпись"; -"Please enter your signature below:" = "Please enter your signature below:"; +"Please enter your signature below:" = "Введите вашу подпись ниже:"; "Please specify a valid sender address." = "Пожалуйста укажите правильный адрес отправителя."; "Please specify a valid reply-to address." = "Пожалуйста укажите правильный адрес для ответа."; @@ -194,7 +195,7 @@ "PRIVATE_item" = "Private"; /* Event+task categories */ -"category_none" = "None"; +"category_none" = "Нет"; "calendar_category_labels" = "Годовщина,День рождения,Деловые,Звонки,Клиенты,Конкуренты,Потребители,Избранное,Вслед за,Подарки,Праздники,Идеи,Встречи,Проблемы,Разное,Персональное,Проекты,Государственный праздник,Статус,Поставщики,Путешествия,Отпуск"; /* Default module */ @@ -202,10 +203,10 @@ "Contacts" = "Адресная книга"; "Mail" = "Почта"; "Last" = "Последнее использование"; -"Default Module :" = "Модуль по умолчанию :"; +"Default Module :" = "Модуль по умолчанию:"; "SOGo Version :" = "Версия SOGo:"; -"Language :" = "Язык :"; +"Language :" = "Язык:"; "choose" = "Выбрать ..."; "Arabic" = "العربية"; "Catalan" = "Català"; @@ -271,12 +272,12 @@ "Untitled Filter" = "Фильтр без названия"; "Subject" = "Subject"; -"From" = "From"; +"From" = "От"; "To" = "To"; "Cc" = "Cc"; "To or Cc" = "To or Cc"; -"Size (Kb)" = "Size (Kb)"; -"Header" = "Header"; +"Size (Kb)" = "Размер (кБ)"; +"Header" = "Заголовок"; "Body" = "Тело письма"; "Flag the message with:" = "Пометить сообщение с:"; "Discard the message" = "Уничтожить сообщение"; diff --git a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings index 98f09d019..45ccd63df 100644 --- a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Desvío"; "Password" = "Contraseña"; "Categories" = "Categorías"; +"Appointments invitations" = "Invitaciones a eventos"; "Name" = "Nombre"; "Color" = "Color"; "Add" = "Añadir"; @@ -104,6 +105,10 @@ "firstWeekOfYear_First4DayWeek" = "Primera semana del año de 4 días"; "firstWeekOfYear_FirstFullWeek" = "Primera semana del año completa"; +"Prevent from being invited to appointments" = "No permitir que otros me inviten a eventos"; +"White list for appointment invitations:" = "Lista de excepciones para invitación a eventos:"; +"Contacts Names" = "Nombre de los contactos"; + /* Default Calendar */ "Default calendar :" = "Calendario por defecto"; "selectedCalendar" = "Calendario seleccionado"; @@ -130,15 +135,6 @@ "Show subscribed mailboxes only" = "Mostrar sólo buzones suscritos"; "Sort messages by threads" = "Ordenar mensajes por conversaciones"; "When sending mail, add unknown recipients to my" = "Al enviar correos, agregar destinatarios desconocidos a mi"; -"Check for new mail:" = "Comprobar si hay nuevos correos: "; -"refreshview_manually" = "Manualmente"; -"refreshview_every_minute" = "Cada minuto"; -"refreshview_every_2_minutes" = "Cada 2 minutos"; -"refreshview_every_5_minutes" = "Cada 5 minutos"; -"refreshview_every_10_minutes" = "Cada 10 minutos"; -"refreshview_every_20_minutes" = "Cada 20 minutos"; -"refreshview_every_30_minutes" = "Cada 30 minutos"; -"refreshview_once_per_hour" = "Cada hora"; "Forward messages:" = "Reenviar mensajes:"; "messageforward_inline" = "Incorporado"; @@ -236,6 +232,16 @@ "Ukrainian" = "Українська"; "Welsh" = "Cymraeg"; +"Refresh View :" = "Actualizar la vista:"; +"refreshview_manually" = "Manualmente"; +"refreshview_every_minute" = "Cada minuto"; +"refreshview_every_2_minutes" = "Cada 2 minutos"; +"refreshview_every_5_minutes" = "Cada 5 minutos"; +"refreshview_every_10_minutes" = "Cada 10 minutos"; +"refreshview_every_20_minutes" = "Cada 20 minutos"; +"refreshview_every_30_minutes" = "Cada 30 minutos"; +"refreshview_once_per_hour" = "Cada hora"; + /* Return receipts */ "When I receive a request for a return receipt:" = "Cuando reciba una petición de un acuse de recibo:"; "Never send a return receipt" = "Nunca enviar un acuse de recibo"; diff --git a/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings b/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings index ebad76559..7a5eb414a 100644 --- a/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings +++ b/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings @@ -12,6 +12,7 @@ "Forward" = "Desvío"; "Password" = "Contraseña"; "Categories" = "Categorías"; +"Appointments invitations" = "Avisos de Eventos"; "Name" = "Nombre"; "Color" = "Color"; "Add" = "Añadir"; @@ -152,6 +153,9 @@ "displayremoteinlineimages_never" = "Nunca"; "displayremoteinlineimages_always" = "Siempre"; +"Auto save every" = "Guardar automáticamente cada"; +"minutes" = "minutos"; + /* Contact */ "Personal Address Book" = "Libreta de direcciones personal"; "Collected Address Book" = "Libreta de direcciones recogidas"; diff --git a/UI/PreferencesUI/UIxFilterEditor.m b/UI/PreferencesUI/UIxFilterEditor.m index 964ff44b6..50ae1af15 100644 --- a/UI/PreferencesUI/UIxFilterEditor.m +++ b/UI/PreferencesUI/UIxFilterEditor.m @@ -1,6 +1,6 @@ /* UIxFilterEditor.m - this file is part of SOGo * - * Copyright (C) 2010-2013 Inverse inc. + * Copyright (C) 2010-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,7 +36,6 @@ { NSString *filterId; NSDictionary *labels; - NSString *folderEncoding; } @end @@ -114,9 +113,9 @@ return [labels jsonRepresentation]; } -- (NSString *) folderEncoding +- (NSString *) sieveFolderEncoding { - return [[SOGoSystemDefaults sharedSystemDefaults] folderEncoding]; + return [[SOGoSystemDefaults sharedSystemDefaults] sieveFolderEncoding]; } @end diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 5017a4bec..a43a8e744 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -959,6 +959,16 @@ static NSArray *reminderValues = nil; [userDefaults setMailDisplayRemoteInlineImages: newType]; } +- (void) setAutoSave: (NSString *) theValue +{ + [userDefaults setMailAutoSave: theValue]; +} + +- (NSString *) autoSave +{ + return [userDefaults mailAutoSave]; +} + /* mail autoreply (vacation) */ - (BOOL) isSieveScriptsEnabled diff --git a/UI/SOGoUI/GNUmakefile b/UI/SOGoUI/GNUmakefile index 2b781caed..7ec6f08dc 100644 --- a/UI/SOGoUI/GNUmakefile +++ b/UI/SOGoUI/GNUmakefile @@ -11,6 +11,8 @@ libSOGoUI_HEADER_FILES_DIR = . libSOGoUI_HEADER_FILES_INSTALL_DIR = /SOGoUI libSOGoUI_INTERFACE_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION) +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo + libSOGoUI_HEADER_FILES += \ \ UIxJSClose.h \ @@ -32,5 +34,6 @@ libSOGoUI_OBJC_FILES += \ ifneq ($(FHS_INSTALL_ROOT),) GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include endif +GNUSTEP_TARGET_LDIR=sogo include $(GNUSTEP_MAKEFILES)/library.make -include GNUmakefile.postamble diff --git a/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings b/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings index a2c92dfe9..3c5891e81 100644 --- a/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings +++ b/UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings @@ -5,6 +5,7 @@ "Create a new event" = "Criar um novo evento"; "Create a new task" = "Criar uma nova tarefa"; "Edit this event or task" = "Editar este evento ou tarefa"; +"Print the current calendar view" = "Imprimir a visualização do calendário atual"; "Delete this event or task" = "Apagar este evento ou tarefa"; "Go to today" = "Vai para hoje"; "Switch to day view" = "Visualizar Dia"; @@ -117,7 +118,7 @@ "Name of the Calendar" = "Nome deste Calendário"; "new" = "Novo"; -"printview" = "Visualizar Impressão"; +"Print view" = "Visualização de Impressão"; "edit" = "Editar"; "delete" = "Apagar"; "proposal" = "Proposta"; @@ -145,6 +146,20 @@ "Hide already accepted and rejected appointments" = "Ocultar apontamentos já aceitos e rejeitados"; "Show already accepted and rejected appointments" = "Exibir apontamentos já aceitos e rejeitados"; +/* Print view */ + +"LIST" = "Lista"; +"Print Settings" = "Configurações de Impressão"; +"Title:" = "Título:"; +"Layout:" = "Layout:"; +"What to Print" = "O que imprimir"; +"Options" = "Opções"; +"Tasks with no due date" = "Tarefas sem data de vencimento"; +"Display working hours only" = "Exibir somente o horário de trabalho"; +"Completed tasks" = "Tarefas Completadas"; +"Display events and tasks colors" = "Exibir eventos e tarefas com cores"; +"Borders" = "Fronteiras"; +"Backgrounds" = "Segundo plano"; /* Appointments */ @@ -225,8 +240,13 @@ "view_future" = "Todos os Eventos Futuros"; "view_selectedday" = "Dia Selecionado"; +"view_not_started" = "Tarefas não iniciadas"; +"view_overdue" = "Tarefas em atraso"; +"view_incomplete" = "Tarefas incompletas"; + "View:" = "Visão:"; -"Title or Description" = "Título ou Descrição"; +"Title, category or location" = "Título, categoria ou localização"; +"Entire content" = "Todo o conteúdo"; "Search" = "Pesquisar"; "Search attendees" = "Pesquisar participantes"; @@ -506,7 +526,7 @@ vtodo_class2 = "(Tarefa Confidencial)"; "Links to this Calendar" = "Links para este Calendário"; "Authenticated User Access" = "Acesso a Usuário Autenticado"; -"CalDAV URL" = "CalDAV url"; +"CalDAV URL" = "CalDAV URL:"; "WebDAV ICS URL" = "WebDAV ICS URL"; "WebDAV XML URL" = "WebDAV XML URL"; @@ -526,6 +546,8 @@ vtodo_class2 = "(Tarefa Confidencial)"; "tagWasRemoved" = "Se você remover este calendário da sincronização, será necessário sincronizar novamente seus dados no dispositivo móvel.\nContinuar?"; "DestinationCalendarError" = "Os calendários de origem e destino são os mesmos. Por favor, tente copiar para outro calendário diferente."; "EventCopyError" = "A cópia falhou. Por favor, tente copiar para um calendário diferente."; +"Please select at least one calendar" = "Por favor, selecione pelo menos um calendário"; + "Open Task..." = "Abrir Tarefa..."; "Mark Completed" = "Marcar como Concluída"; diff --git a/UI/Scheduler/GNUmakefile b/UI/Scheduler/GNUmakefile index 9f96857a6..4c0765244 100644 --- a/UI/Scheduler/GNUmakefile +++ b/UI/Scheduler/GNUmakefile @@ -23,12 +23,11 @@ SchedulerUI_OBJC_FILES = \ UIxCalFolderActions.m \ \ UIxCalView.m \ - UIxCalViewPrint.m \ + UIxCalViewPrint.m \ UIxCalDayView.m \ UIxCalMulticolumnDayView.m \ UIxCalWeekView.m \ UIxCalMonthView.m \ - UIxAptTableView.m \ \ UIxCalListingActions.m \ UIxCalMainActions.m \ @@ -53,9 +52,6 @@ SchedulerUI_RESOURCE_FILES += \ SchedulerUI_RESOURCE_FILES += \ Toolbars/SOGoAppointmentFolders.toolbar \ Toolbars/SOGoAppointmentObject.toolbar \ - Toolbars/SOGoAppointmentObjectAccept.toolbar \ - Toolbars/SOGoAppointmentObjectDecline.toolbar \ - Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar \ Toolbars/SOGoTaskObject.toolbar \ Toolbars/SOGoComponentClose.toolbar \ Toolbars/SOGoEmpty.toolbar @@ -72,6 +68,7 @@ SchedulerUI_RESOURCE_FILES += \ ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/ +ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings b/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings index 893f9d4dd..a987dcfbf 100644 --- a/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings +++ b/UI/Scheduler/SpanishArgentina.lproj/Localizable.strings @@ -29,7 +29,7 @@ /* Week */ "Week" = "Semana"; -"this week" = "ésta semana"; +"this week" = "esta semana"; "Week %d" = "Semana %d"; @@ -38,14 +38,14 @@ /* Month */ -"this month" = "éste mes"; +"this month" = "este mes"; "Previous Month" = "Mes anterior"; "Next Month" = "Próximo mes"; /* Year */ -"this year" = "éste año"; +"this year" = "este año"; /* Menu */ @@ -155,7 +155,11 @@ "What to Print" = "Qué imprimir"; "Options" = "Opciones"; "Tasks with no due date" = "Tareas sin fecha de vencimiento"; +"Display working hours only" = "Mostrar solo las horas laborables"; "Completed tasks" = "Tareas completadas"; +"Display events and tasks colors" = "Mostrar los colores de los eventos y las tareas"; +"Borders" = "Bordes"; +"Backgrounds" = "Fondos"; /* Appointments */ @@ -542,6 +546,8 @@ vtodo_class2 = "(Tarea confidencial)"; "tagWasRemoved" = "Si quita este calendario de la sincronización, necesitará recargar los datos en su teléfono móvil.\n¿Continuar?"; "DestinationCalendarError" = "El calendario de origen y el de destino son iguales. Por favor, intente copiar a otro calendario."; "EventCopyError" = "La copia falló. Por favor, intente copiar a un calendario distinto."; +"Please select at least one calendar" = "Por favor, seleccione al menos un calendario"; + "Open Task..." = "Abrir tarea..."; "Mark Completed" = "Marcar como completo"; diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar deleted file mode 100644 index e3913afc1..000000000 --- a/UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar +++ /dev/null @@ -1,7 +0,0 @@ -( /* the toolbar groups -*-cperl-*- */ - ( { link = "#"; - isSafe = NO; - label = "accept"; - onclick = "return modifyEvent(this, 'accept');"; - image = "tb-ab-properties-flat-24x24.png"; } ) -) diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar deleted file mode 100644 index bb967d8ea..000000000 --- a/UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar +++ /dev/null @@ -1,12 +0,0 @@ -( /* the toolbar groups -*-cperl-*- */ - ( { link = "#"; - isSafe = NO; - label = "accept"; - onclick = "return modifyEvent(this, 'accept');"; - image = "tb-ab-properties-flat-24x24.png"; }, - { link = "#"; - isSafe = NO; - label = "decline"; - onclick = "return modifyEvent(this, 'decline');"; - image = "tb-mail-stop-flat-24x24.png"; } ) -) diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar deleted file mode 100644 index 347b8f8cf..000000000 --- a/UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar +++ /dev/null @@ -1,7 +0,0 @@ -( /* the toolbar groups -*-cperl-*- */ - ( { link = "#"; - isSafe = NO; - label = "decline"; - onclick = "return modifyEvent(this, 'decline');"; - image = "tb-mail-stop-flat-24x24.png"; } ) -) diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index 86c26153b..653226628 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -51,6 +51,7 @@ #import #import #import +#import #import #import #import @@ -80,7 +81,7 @@ isTransparent = NO; sendAppointmentNotifications = YES; componentCalendar = nil; - + user = [[self context] activeUser]; ASSIGN (dateFormatter, [user dateFormatterInContext: context]); } @@ -111,6 +112,11 @@ return event; } +- (NSString *) rsvpURL +{ + return [NSString stringWithFormat: @"%@/rsvpAppointment", + [[self clientObject] baseURL]]; +} - (NSString *) saveURL { return [NSString stringWithFormat: @"%@/saveAsAppointment", @@ -390,6 +396,137 @@ } } +// +// +// +- (id ) rsvpAction +{ + iCalPerson *delegatedAttendee; + NSDictionary *message; + WOResponse *response; + WORequest *request; + iCalAlarm *anAlarm; + NSString *status; + + int replyList, reminderList; + + request = [context request]; + message = [[request contentAsString] objectFromJSONString]; + + delegatedAttendee = nil; + anAlarm = nil; + status = nil; + + replyList = [[message objectForKey: @"replyList"] intValue]; + + switch (replyList) + { + case 0: + status = @"ACCEPTED"; + break; + + case 1: + status = @"DECLINED"; + break; + + case 2: + status = @"NEEDS-ACTION"; + break; + + case 3: + status = @"TENTATIVE"; + break; + + case 4: + default: + { + NSString *delegatedEmail, *delegatedUid; + SOGoUser *user; + + status = @"DELEGATED"; + delegatedEmail = [[message objectForKey: @"delegatedTo"] stringByTrimmingSpaces]; + + if ([delegatedEmail length]) + { + user = [context activeUser]; + delegatedAttendee = [iCalPerson new]; + [delegatedAttendee autorelease]; + [delegatedAttendee setEmail: delegatedEmail]; + delegatedUid = [delegatedAttendee uid]; + if (delegatedUid) + { + SOGoUser *delegatedUser; + delegatedUser = [SOGoUser userWithLogin: delegatedUid]; + [delegatedAttendee setCn: [delegatedUser cn]]; + } + + [delegatedAttendee setRole: @"REQ-PARTICIPANT"]; + [delegatedAttendee setRsvp: @"TRUE"]; + [delegatedAttendee setParticipationStatus: iCalPersonPartStatNeedsAction]; + [delegatedAttendee setDelegatedFrom: + [NSString stringWithFormat: @"mailto:%@", [[user allEmails] objectAtIndex: 0]]]; + } + else + return [NSException exceptionWithHTTPStatus: 400 + reason: @"missing 'to' parameter"]; + } + break; + } + + // Extract the user alarm, if any + reminderList = [[message objectForKey: @"reminderList"] intValue]; + + if ([[message objectForKey: @"reminderList"] isEqualToString: @"WONoSelectionString"] || reminderList == 5 || reminderList == 10 || reminderList == 14) + { + // No selection, wipe alarm which will be done in changeParticipationStatus... + } + else if (reminderList == 15) + { + // Custom + anAlarm = [iCalAlarm alarmForEvent: [self event] + owner: [[self clientObject] ownerInContext: context] + action: [message objectForKey: @"reminderAction"] + unit: [message objectForKey: @"reminderUnit"] + quantity: [message objectForKey: @"reminderQuantity"] + reference: [message objectForKey: @"reminderReference"] + reminderRelation: [message objectForKey: @"reminderRelation"] + emailAttendees: [[message objectForKey: @"reminderEmailAttendees"] boolValue] + emailOrganizer: [[message objectForKey: @"reminderEmailOrganizer"] boolValue]]; + } + else + { + // Standard + NSString *aValue; + + aValue = [[UIxComponentEditor reminderValues] objectAtIndex: reminderList]; + + // Predefined alarm + if ([aValue length]) + { + iCalTrigger *aTrigger; + + anAlarm = [[[iCalAlarm alloc] init] autorelease]; + aTrigger = [iCalTrigger elementWithTag: @"TRIGGER"]; + [aTrigger setValueType: @"DURATION"]; + [anAlarm setTrigger: aTrigger]; + [anAlarm setAction: @"DISPLAY"]; + [aTrigger setSingleValue: aValue forKey: @""]; + } + } + + response = (WOResponse *)[[self clientObject] changeParticipationStatus: status + withDelegate: delegatedAttendee + alarm: anAlarm]; + + if (!response) + response = [self responseWith204]; + + return response; +} + +// +// +// - (id ) saveAction { SOGoAppointmentFolder *previousCalendar; @@ -560,7 +697,7 @@ actionName = [[request requestHandlerPath] lastPathComponent]; return ([[self clientObject] conformsToProtocol: @protocol (SOGoComponentOccurence)] - && [actionName hasPrefix: @"save"]); + && ([actionName hasPrefix: @"save"] || [actionName hasPrefix: @"rsvp"])); } - (void) takeValuesFromRequest: (WORequest *) _rq @@ -637,81 +774,4 @@ } -- (id) _statusChangeAction: (NSString *) newStatus -{ - [[self clientObject] changeParticipationStatus: newStatus - withDelegate: nil]; - - return [self responseWith204]; -} - -- (id) acceptAction -{ - return [self _statusChangeAction: @"ACCEPTED"]; -} - -- (id) declineAction -{ - return [self _statusChangeAction: @"DECLINED"]; -} - -- (id) needsActionAction -{ - return [self _statusChangeAction: @"NEEDS-ACTION"]; -} - -- (id) tentativeAction -{ - return [self _statusChangeAction: @"TENTATIVE"]; -} - -- (id) delegateAction -{ -// BOOL receiveUpdates; - NSString *delegatedEmail, *delegatedUid; - iCalPerson *delegatedAttendee; - SOGoUser *user; - WORequest *request; - WOResponse *response; - - response = nil; - request = [context request]; - delegatedEmail = [request formValueForKey: @"to"]; - if ([delegatedEmail length]) - { - user = [context activeUser]; - delegatedAttendee = [iCalPerson new]; - [delegatedAttendee autorelease]; - [delegatedAttendee setEmail: delegatedEmail]; - delegatedUid = [delegatedAttendee uid]; - if (delegatedUid) - { - SOGoUser *delegatedUser; - delegatedUser = [SOGoUser userWithLogin: delegatedUid]; - [delegatedAttendee setCn: [delegatedUser cn]]; - } - - [delegatedAttendee setRole: @"REQ-PARTICIPANT"]; - [delegatedAttendee setRsvp: @"TRUE"]; - [delegatedAttendee setParticipationStatus: iCalPersonPartStatNeedsAction]; - [delegatedAttendee setDelegatedFrom: - [NSString stringWithFormat: @"mailto:%@", [[user allEmails] objectAtIndex: 0]]]; - -// receiveUpdates = [[request formValueForKey: @"receiveUpdates"] boolValue]; -// if (receiveUpdates) -// [delegatedAttendee setRole: @"NON-PARTICIPANT"]; - - response = (WOResponse*)[[self clientObject] changeParticipationStatus: @"DELEGATED" - withDelegate: delegatedAttendee]; - } - else - response = [NSException exceptionWithHTTPStatus: 400 - reason: @"missing 'to' parameter"]; - - if (!response) - response = [self responseWith204]; - - return response; -} - @end diff --git a/UI/Scheduler/UIxAptTableView.m b/UI/Scheduler/UIxAptTableView.m deleted file mode 100644 index a634f9257..000000000 --- a/UI/Scheduler/UIxAptTableView.m +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (C) 2000-2003 SKYRIX Software AG - - This file is part of OGo - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#import - -@class NSArray, NSCalendarDate; - -@interface UIxAptTableView : SoComponent -{ - NSArray *appointments; - id appointment; -} - -/* accessors */ - -- (NSArray *)appointments; -- (id)appointment; - -@end - -@implementation UIxAptTableView - -- (void)dealloc { - [self->appointment release]; - [self->appointments release]; - [super dealloc]; -} - -/* accessors */ - -- (void)setAppointments:(NSArray *)_apts { - ASSIGN(self->appointments, _apts); -} -- (NSArray *)appointments { - return self->appointments; -} - -- (void)setAppointment:(id)_apt { - ASSIGN(self->appointment, _apt); -} -- (id)appointment { - return self->appointment; -} - -- (NSString *)appointmentViewURL { - id pkey; - - if ((pkey = [[self appointment] valueForKey:@"dateId"]) == nil) - return nil; - - return [NSString stringWithFormat:@"%@/view", pkey]; -} - -@end /* UIxAptTableView */ diff --git a/UI/Scheduler/UIxCalView.m b/UI/Scheduler/UIxCalView.m index bbf7b4608..40677b6e9 100644 --- a/UI/Scheduler/UIxCalView.m +++ b/UI/Scheduler/UIxCalView.m @@ -1,8 +1,6 @@ /* UIxCalView.m - this file is part of SOGo * - * Copyright (C) 2006-2009 Inverse inc. - * - * Author: Wolfgang Sourdeau + * Copyright (C) 2006-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -584,7 +582,7 @@ [uri appendString: @"Groups/_custom_"]; [uri appendString: uidsString]; [uri appendString: @"/"]; - NSLog (@"Group URI = '%@'", uri); + //NSLog (@"Group URI = '%@'", uri); } else { diff --git a/UI/Scheduler/UIxCalendarProperties.h b/UI/Scheduler/UIxCalendarProperties.h index 157653dc2..de17b6117 100644 --- a/UI/Scheduler/UIxCalendarProperties.h +++ b/UI/Scheduler/UIxCalendarProperties.h @@ -1,9 +1,6 @@ /* UIxCalendarProperties.m - this file is part of SOGo * - * Copyright (C) 2008-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * Ludovic Marcotte + * Copyright (C) 2008-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/UI/Scheduler/UIxCalendarProperties.m b/UI/Scheduler/UIxCalendarProperties.m index 3817ad48d..8f0ec4e81 100644 --- a/UI/Scheduler/UIxCalendarProperties.m +++ b/UI/Scheduler/UIxCalendarProperties.m @@ -1,9 +1,6 @@ /* UIxCalendarProperties.m - this file is part of SOGo * - * Copyright (C) 2008-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * Ludovic Marcotte + * Copyright (C) 2008-2014 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -181,15 +178,6 @@ [calendar setShowCalendarTasks: new]; } -- (BOOL) userIsOwner -{ - NSString *userLogin; - - userLogin = [[context activeUser] login]; - - return ([userLogin isEqualToString: [calendar ownerInContext: context]]); -} - - (BOOL) isPublicAccessEnabled { // NOTE: This method is the same found in Common/UIxAclEditor.m diff --git a/UI/Scheduler/UIxComponentEditor.h b/UI/Scheduler/UIxComponentEditor.h index 6120901d8..201065c11 100644 --- a/UI/Scheduler/UIxComponentEditor.h +++ b/UI/Scheduler/UIxComponentEditor.h @@ -38,6 +38,7 @@ id item; id attendee; + NSString *rsvpURL; NSString *saveURL; NSMutableArray *calendarList; NSDictionary *organizerProfile; @@ -62,7 +63,7 @@ NSString *dateFormat; NSMutableDictionary *jsonAttendees; - + NSString *reminder; NSString *reminderQuantity; NSString *reminderUnit; @@ -184,6 +185,8 @@ - (BOOL) isWriteableClientObject; - (NSException *) validateObjectForStatusChange; ++ (NSArray *) reminderValues; + @end #endif /* UIXCOMPONENTEDITOR_H */ diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 77a4d032a..c1d666e63 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -1,6 +1,6 @@ /* UIxComponentEditor.m - this file is part of SOGo * - * Copyright (C) 2006-2014 Inverse inc. + * Copyright (C) 2006-2015 Inverse inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,6 +51,7 @@ #import #import +#import #import #import #import @@ -225,7 +226,7 @@ iRANGE(2); [attendee release]; [jsonAttendees release]; [calendarList release]; - + [reminder release]; [reminderQuantity release]; [reminderUnit release]; @@ -593,7 +594,7 @@ iRANGE(2); ASSIGN (reminderUnit, @"MINUTES"); break; default: - NSLog(@"Cannot process duration unit: '%c'", c); + //NSLog(@"Cannot process duration unit: '%c'", c); break; } } @@ -683,12 +684,16 @@ iRANGE(2); ASSIGN (ownerAsAttendee, [component findAttendeeWithEmail: (id)ownerEmail]); } } -// /* cycles */ -// if ([component isRecurrent]) -// { -// rrule = [[component recurrenceRules] objectAtIndex: 0]; -// [self adjustCycleControlsForRRule: rrule]; -// } +} + +- (void) setRSVPURL: (NSString *) theURL +{ + rsvpURL = theURL; +} + +- (NSString *) rsvpURL +{ + return rsvpURL; } - (void) setSaveURL: (NSString *) newSaveURL @@ -1423,7 +1428,8 @@ iRANGE(2); - (void) setComponentCalendar: (SOGoAppointmentFolder *) _componentCalendar { - ASSIGN(componentCalendar, _componentCalendar); + if (_componentCalendar) + ASSIGN(componentCalendar, _componentCalendar); } /* priorities */ @@ -1881,7 +1887,9 @@ RANGE(2); [component setAttendees: newAttendees]; } else - NSLog(@"Error scanning following JSON:\n%@", json); + { + //NSLog(@"Error scanning following JSON:\n%@", json); + } } } @@ -2168,40 +2176,7 @@ RANGE(2); } } -- (void) _appendAttendees: (NSArray *) attendees - toEmailAlarm: (iCalAlarm *) alarm -{ - NSMutableArray *aAttendees; - int count, max; - iCalPerson *currentAttendee, *aAttendee; - max = [attendees count]; - aAttendees = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - currentAttendee = [attendees objectAtIndex: count]; - aAttendee = [iCalPerson elementWithTag: @"attendee"]; - [aAttendee setCn: [currentAttendee cn]]; - [aAttendee setEmail: [currentAttendee rfc822Email]]; - [aAttendees addObject: aAttendee]; - } - [alarm setAttendees: aAttendees]; -} - -- (void) _appendOrganizerToEmailAlarm: (iCalAlarm *) alarm -{ - NSString *uid; - NSDictionary *ownerIdentity; - iCalPerson *aAttendee; - - uid = [[self clientObject] ownerInContext: context]; - ownerIdentity = [[SOGoUser userWithLogin: uid roles: nil] - defaultIdentity]; - aAttendee = [iCalPerson elementWithTag: @"attendee"]; - [aAttendee setCn: [ownerIdentity objectForKey: @"fullName"]]; - [aAttendee setEmail: [ownerIdentity objectForKey: @"email"]]; - [alarm addChild: aAttendee]; -} - (void) takeValuesFromRequest: (WORequest *) _rq inContext: (WOContext *) _ctx @@ -2236,68 +2211,43 @@ RANGE(2); [component removeAllAlarms]; else { - iCalTrigger *aTrigger; iCalAlarm *anAlarm; NSString *aValue; NSUInteger index; - anAlarm = [iCalAlarm new]; - index = [reminderItems indexOfObject: reminder]; - - aTrigger = [iCalTrigger elementWithTag: @"TRIGGER"]; - [aTrigger setValueType: @"DURATION"]; - [anAlarm setTrigger: aTrigger]; - aValue = [reminderValues objectAtIndex: index]; - if ([aValue length]) { - // Predefined alarm - [anAlarm setAction: @"DISPLAY"]; - [aTrigger setSingleValue: aValue forKey: @""]; - } - else { - // Custom alarm - if ([reminderAction length] > 0 && [reminderUnit length] > 0) - { - [anAlarm setAction: [reminderAction uppercaseString]]; - if ([reminderAction isEqualToString: @"email"]) - { - [anAlarm removeAllAttendees]; - if (reminderEmailAttendees) - [self _appendAttendees: [component attendees] - toEmailAlarm: anAlarm]; - if (reminderEmailOrganizer) - [self _appendOrganizerToEmailAlarm: anAlarm]; - [anAlarm setSummary: [component summary]]; - [anAlarm setComment: [component comment]]; - } - - if ([reminderReference caseInsensitiveCompare: @"BEFORE"] == NSOrderedSame) - aValue = [NSString stringWithString: @"-P"]; - else - aValue = [NSString stringWithString: @"P"]; - - if ([reminderUnit caseInsensitiveCompare: @"MINUTES"] == NSOrderedSame || - [reminderUnit caseInsensitiveCompare: @"HOURS"] == NSOrderedSame) - aValue = [aValue stringByAppendingString: @"T"]; - - aValue = [aValue stringByAppendingFormat: @"%i%@", - [reminderQuantity intValue], - [reminderUnit substringToIndex: 1]]; - [aTrigger setSingleValue: aValue forKey: @""]; - [aTrigger setRelationType: reminderRelation]; - } - else - { - [anAlarm release]; - anAlarm = nil; - } - } + + // Predefined alarm + if ([aValue length]) + { + iCalTrigger *aTrigger; + + anAlarm = [[[iCalAlarm alloc] init] autorelease]; + aTrigger = [iCalTrigger elementWithTag: @"TRIGGER"]; + [aTrigger setValueType: @"DURATION"]; + [anAlarm setTrigger: aTrigger]; + [anAlarm setAction: @"DISPLAY"]; + [aTrigger setSingleValue: aValue forKey: @""]; + } + else + { + // Custom alarm + anAlarm = [iCalAlarm alarmForEvent: component + owner: [[self clientObject] ownerInContext: context] + action: reminderAction + unit: reminderUnit + quantity: reminderQuantity + reference: reminderReference + reminderRelation: reminderRelation + emailAttendees: reminderEmailAttendees + emailOrganizer: reminderEmailOrganizer]; + } + if (anAlarm) { [component removeAllAlarms]; [component addToAlarms: anAlarm]; - [anAlarm release]; } } @@ -2597,4 +2547,9 @@ RANGE(2); return response; } ++ (NSArray *) reminderValues +{ + return reminderValues; +} + @end diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index c13980130..da074912e 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -241,6 +241,11 @@ pageName = "UIxAppointmentEditor"; actionName = "save"; }; + rsvpAppointment = { + protectedBy = "RespondToComponent"; + pageName = "UIxAppointmentEditor"; + actionName = "rsvp"; + }; saveAsAppointment = { protectedBy = "ModifyComponent"; pageName = "UIxAppointmentEditor"; @@ -256,31 +261,6 @@ actionClass = "UIxComponentEditor"; actionName = "raw"; }; - accept = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "accept"; - }; - decline = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "decline"; - }; - delegate = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "delegate"; - }; - tentative = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "tentative"; - }; - needsaction = { - protectedBy = "RespondToComponent"; - pageName = "UIxAppointmentEditor"; - actionName = "needsAction"; - }; adjust = { protectedBy = "ModifyComponent"; actionClass = "UIxAppointmentActions"; diff --git a/UI/Templates/MailerUI/UIxMailEditor.wox b/UI/Templates/MailerUI/UIxMailEditor.wox index ea18d9c4f..51a3e0afc 100644 --- a/UI/Templates/MailerUI/UIxMailEditor.wox +++ b/UI/Templates/MailerUI/UIxMailEditor.wox @@ -10,7 +10,7 @@ className="UIxPageFrame" title="panelTitle" const:popup="YES" - const:userDefaultsKeys="SOGoMailComposeMessageType,SOGoMailReplyPlacement,SOGoMailSignature" + const:userDefaultsKeys="SOGoMailComposeMessageType,SOGoMailReplyPlacement,SOGoMailSignature,SOGoMailAutoSave,SOGoDraftsFolderName" const:jsFiles="UIxMailToSelection.js,ckeditor/ckeditor.js,SOGoAutoCompletion.js,ContactsUI.js,jquery-ui.js,jquery.fileupload.js,jquery.iframe-transport.js" const:cssFiles="jquery.fileupload.css">