Compare commits

...
391 Commits
Author SHA1 Message Date
Francis Lachapelle c9b9150b96 Update ChangeLog 2017-05-09 09:06:22 -04:00
Francis Lachapelle 4d490d0f1e Preparation for release 3.2.9 2017-05-09 09:04:31 -04:00
Francis Lachapelle bc23130f9b (i18n) Update translations 2017-05-09 09:00:33 -04:00
InverseBot 28bc489c1a (js/css) Update generated files 2017-05-09 01:22:56 -04:00
Francis Lachapelle 650f337c41 (js/css) Update generated files 2017-05-08 16:08:22 -04:00
Francis Lachapelle 8de9b8ff53 Update time zones to version 2017b 2017-05-08 16:00:10 -04:00
Francis Lachapelle 8b812ba4f0 (js) Minor JavaScript code cleanup 2017-05-08 15:46:48 -04:00
Francis Lachapelle 836700fb7e (js) Improve CAS handling 2017-05-08 15:43:10 -04:00
Francis Lachapelle ba583f41b1 (i18n) Update translations 2017-05-08 15:06:31 -04:00
Francis Lachapelle 0e82550f6b Update SOGoParentFolder.h 2017-05-08 14:44:13 -04:00
Francis Lachapelle 0185ba9d46 Fix mail delegation of pristine user accounts
Fixes #4160
2017-05-08 11:23:32 -04:00
Ludovic Marcotte 9700b93ad1 Updated NEWS 2017-05-08 10:46:39 -04:00
Ludovic Marcotte 63cb80142b (fix) make sure to use crypt as the scheme for md5/sha256/sha512 (fixes #4137) 2017-05-08 10:44:12 -04:00
InverseBot c3ef225a02 (js/css) Update generated files 2017-05-08 01:23:36 -04:00
InverseBot b42876bb0a (js/css) Update generated files 2017-05-07 01:17:20 -04:00
InverseBot da4033eeab (js/css) Update generated files 2017-05-04 01:17:26 -04:00
Francis Lachapelle f1329a3d36 (i18n) Update German translation 2017-05-02 09:56:30 -04:00
Francis Lachapelle b46781c693 Silent sogo-ealarms-notify
Fixes #4157
2017-04-27 09:40:24 -04:00
Francis Lachapelle ef5728dcaf Properly honor "include in freebusy"
Fixes #3354
2017-04-27 09:38:07 -04:00
Francis Lachapelle 663a0b60dd (feat) Configurable Web animation level 2017-04-25 16:35:39 -04:00
Francis Lachapelle 59dbef5ee7 Avoid duplicated emails in LDAP-based addressbook
Fixes #4129
2017-04-25 14:49:29 -04:00
InverseBot 4caff58918 (js/css) Update generated files 2017-04-25 01:18:12 -04:00
Francis Lachapelle 634cbe3d1b (js) Support SOGoLDAPContactInfoAttrbute 2017-04-24 16:15:39 -04:00
Francis Lachapelle 3d0c958a19 (js) Keep form pristine when changing passwords
Fixes #4138
2017-04-24 12:08:15 -04:00
Francis Lachapelle da44afdcf5 (i18n) Update translations 2017-04-24 11:37:49 -04:00
InverseBot 11f847cdfb (js/css) Update generated files 2017-04-22 01:18:32 -04:00
Francis Lachapelle 5f71ee4d52 (doc) Typo 2017-04-21 16:02:10 -04:00
Francis Lachapelle 68eae92d2d (doc) Exclude GNUstep packages from EPEL 2017-04-21 15:32:33 -04:00
Ludovic Marcotte 9459185059 Updated NEWS 2017-04-21 15:31:26 -04:00
Ludovic Marcotte a9763e94a4 (feat) added photo support in GAL search ops 2017-04-21 15:29:34 -04:00
Ludovic Marcotte 5c573b9a76 (fix) small fixes over previous commit 2017-04-21 14:12:48 -04:00
Ludovic Marcotte 513d81eb59 (fix) LDIF to vCard conversion for non-handled multi-value attributes (fixes #4086) 2017-04-21 12:31:54 -04:00
Francis Lachapelle 2b4e357da6 (js) Improve handling of IMAP timeout handling
For external accounts only.
2017-04-21 11:58:52 -04:00
Ludovic Marcotte ab50a41a86 (fix) email reminders sent multiple times (fixes #4100) 2017-04-21 08:49:56 -04:00
Ludovic Marcotte 7582ec8462 Updated comment 2017-04-20 14:35:44 -04:00
Ludovic Marcotte dd6b77a25b Updated NEWS 2017-04-20 14:31:26 -04:00
Ludovic Marcotte 0091ff749a (fix) handle properly windows-1255 charset (fixes #4124) 2017-04-20 14:29:15 -04:00
InverseBot c09dff3fc8 (js/css) Update generated files 2017-04-13 01:24:28 -04:00
Ludovic Marcotte 8a59180c0e Updated NEWS 2017-04-12 16:37:14 -04:00
Ludovic Marcotte d87dc6cdf2 (fix) enhance display of all-day invitations (fixes #4145)
Conflicts:
	SoObjects/Appointments/SOGoAptMailNotification.m
2017-04-12 16:36:41 -04:00
Francis Lachapelle 0af81b0831 (email alarms) Fix recipient header encoding 2017-04-12 16:22:15 -04:00
Francis Lachapelle 6fd9927092 (js) Fix email reminder with attendees
Fixes #4115
2017-04-12 14:56:38 -04:00
Francis Lachapelle 8bcda19799 (web) Fix renaming a mailbox with special chars 2017-04-12 13:41:24 -04:00
Ludovic Marcotte 5570d28d12 Updated NEWS 2017-04-12 13:02:10 -04:00
Ludovic Marcotte b8369ddb37 (fix) don't send IMIP invitation request/update for ALL EAS clients (fixes #4022) 2017-04-12 13:01:01 -04:00
Ludovic Marcotte e1ea6392c2 (fix) set RSVP when sending events invite 2017-04-12 12:59:53 -04:00
Ludovic Marcotte 011e112a1a Updated NEWS 2017-04-12 09:01:32 -04:00
Ludovic Marcotte 7d396a51f5 (feat) email alarms now have pretty formatting (fixes #805) 2017-04-12 08:59:29 -04:00
InverseBot dbf5039011 (js/css) Update generated files 2017-04-12 01:20:37 -04:00
Francis Lachapelle 76e6c064f7 Improve IMAP error handling in Mailer module 2017-04-11 15:42:36 -04:00
Francis Lachapelle 04f930dba5 (js) Always show center list on small devices 2017-04-11 12:00:00 -04:00
Francis Lachapelle 08fcee67bd Improve IMAP error handling in Mailer module 2017-04-11 11:47:47 -04:00
Ludovic Marcotte cc9602fbc8 Updated NEWS 2017-04-11 10:15:58 -04:00
Ludovic Marcotte c92d489017 (fix) remove over EAS alarms if we don't want them (fixes #4059) 2017-04-11 10:13:56 -04:00
Ludovic Marcotte 4cf59cd92e Updated NEWS 2017-04-07 14:18:20 -04:00
Ludovic Marcotte c4ad338aed (fix) initialize variable to avoid strange nil-return value on invocation (fixes #4048) 2017-04-07 14:16:18 -04:00
Ludovic Marcotte c8708d9164 Updated NEWS 2017-04-07 13:45:07 -04:00
Ludovic Marcotte 9bf7247835 (fix) correctly set flags when ReplaceMime is set (fixes #4133) 2017-04-07 13:43:18 -04:00
Francis Lachapelle ed3f794226 Fix attachment path when inside multiple parts 2017-04-06 14:31:41 -04:00
Ludovic Marcotte b9f4947f8a (fix) check if found before changing location 2017-04-06 14:24:25 -04:00
Ludovic Marcotte f83d6a20a1 (fix) protect ourself from broken SOPE/SOGo installs (fixes #4117) 2017-04-06 11:02:59 -04:00
Francis Lachapelle 8ff189229b [web] Fix exception when partstate is not known 2017-04-05 16:22:28 -04:00
Francis Lachapelle 4c1de4cecc Update NEWS file 2017-04-05 14:00:02 -04:00
InverseBot a7254fe4dd (js/css) Update generated files 2017-04-04 01:25:28 -04:00
Ludovic Marcotte 308938dcfa Updated NEWS 2017-03-29 10:20:59 -04:00
Ludovic Marcotte c11d961bf3 (fix) avoid escaping values that are quoted (fixes #3296) 2017-03-29 10:18:38 -04:00
InverseBot 4e82820db7 (js/css) Update generated files 2017-03-25 01:31:35 -04:00
Ludovic Marcotte 26dac618d0 (fix) more fixes for #3905 2017-03-24 12:38:02 -04:00
Ludovic Marcotte f1cc36b533 (fix) more fixes for #3905 2017-03-24 12:37:55 -04:00
Francis Lachapelle cf07f5746c Update ChangeLog 2017-03-24 09:46:32 -04:00
Francis Lachapelle a328f022cb (css) Update default theme 2017-03-24 09:45:56 -04:00
Francis Lachapelle 46c7af5fdd (js/css) Update generated files 2017-03-24 09:43:51 -04:00
Francis Lachapelle 7065c4f765 Preparation for release 3.2.8 2017-03-24 09:42:33 -04:00
Francis Lachapelle 2c8d1d0a26 (i18n) Update translations 2017-03-24 09:32:46 -04:00
InverseBot dab48bfc60 (js/css) Update generated files 2017-03-24 01:24:52 -04:00
Francis Lachapelle b0cc012849 (css,js) Update md to v1.1.3-master-e3f9772 2017-03-23 16:11:32 -04:00
Francis Lachapelle 1d028e4cf5 Expose default value SOGoMailAddOutgoingAddresses
Fixes #4064
2017-03-23 15:42:05 -04:00
Francis Lachapelle 4dcc1af46a (js) Improve recurrence editor 2017-03-23 14:01:28 -04:00
Francis Lachapelle c57f42b44b (js) Fix possible undefined variable 2017-03-23 13:58:34 -04:00
Francis Lachapelle 736921bdf7 (js) Fix display of category colors of components 2017-03-23 13:55:14 -04:00
Francis Lachapelle 0cc7c6be3d (js) Hide Copy/Move menu options with a single AB 2017-03-23 13:07:07 -04:00
Francis Lachapelle b7bc59d599 Enable Save btn after deleting attribute from card
Fixes #4095
2017-03-23 12:48:17 -04:00
InverseBot 2f92484064 (js/css) Update generated files 2017-03-23 01:24:54 -04:00
Francis Lachapelle b463fd4eda (js) Drop sgTransformOnBlur directive
The md-chips component has now a functional "md-add-on-blur" functionality.

Fixes #3944
2017-03-22 15:35:05 -04:00
Francis Lachapelle 75aaef0f3d (js) Restrict special mailboxes to the top level
Fixes #6963
2017-03-22 14:53:07 -04:00
Francis Lachapelle e7a06c42a4 (js) Fix sanitisation of flags in Sieve filters
Fixes #4087
2017-03-22 13:26:43 -04:00
Francis Lachapelle 5ff8463fba (js) Split string when pasting multiple addresses
Fixes #4097
2017-03-22 11:58:05 -04:00
Francis Lachapelle bc8146ef5d Remove debugging output 2017-01-29 18:02:44 -05:00
Ludovic Marcotte b25480f228 Updated NEWS 2017-03-18 15:37:45 -04:00
Ludovic Marcotte 585cda36d1 (fix) fix opacity in freebusy over EAS 2017-03-18 15:34:56 -04:00
Ludovic Marcotte b6d9c3e8e0 (fix) remove old code conflicting with #3905 2017-03-15 10:39:22 -04:00
Ludovic Marcotte ce8f2e9481 (fix) fixed task sorting on multiple categories 2017-03-14 14:18:53 -04:00
InverseBot cb532de83a (js/css) Update generated files 2017-03-14 09:09:24 -04:00
Francis Lachapelle 1aebad854b (js) Add missing variable declaration 2017-03-10 15:05:46 -05:00
Francis Lachapelle 9f6bc8a749 (js) Fix freebusy coverage of newly created event 2017-03-10 14:50:27 -05:00
Francis Lachapelle d24ff75ecf (js) Fix button to remove an attendee 2017-03-10 14:49:32 -05:00
Francis Lachapelle f60ffa923e (js) Display the attendees editor automatically 2017-03-10 14:48:53 -05:00
Francis Lachapelle 19512a85d2 (html) Caption for freebusy data of attendees 2017-03-10 14:43:02 -05:00
Francis Lachapelle baa6d39e28 (css) Generated no-animation.css 2017-03-10 06:36:14 -05:00
Ludovic Marcotte 5d9673415a (fix) don't abort on unhandled requests 2017-03-09 13:58:05 -05:00
Francis Lachapelle 50f25b0597 (i18n) Update translations 2017-03-09 12:19:12 -05:00
Francis Lachapelle 0a0f8a8d89 (css) Custom CSS for IE 2017-03-09 12:16:51 -05:00
Francis Lachapelle 489e35158c (css) Restore lost .md-fab-overlap-bottom class 2017-03-09 09:13:03 -05:00
InverseBot 11d9df6e6a (js/css) Update generated files 2017-03-09 01:26:19 -05:00
Francis Lachapelle e5dc76cc19 (js) Check alarms only if Calendar is accessible
Fixes #4067
2017-03-08 16:15:15 -05:00
Francis Lachapelle ab7ec63f4b Fix typo in Scheduler
Fixes #4072
2017-03-08 16:05:03 -05:00
Francis Lachapelle 1964fdebcb (html) Improve display of vacation message in pref 2017-03-08 16:05:03 -05:00
InverseBot 5b6807b78c (js/css) Update generated files 2017-03-08 09:42:14 -05:00
Ludovic Marcotte 9603971c1f (fix) wrong var type declaration 2017-03-08 09:31:19 -05:00
Ludovic Marcotte 4ae8961947 (fix) handle when mail starts with Bcc header (fixes #4073) 2017-03-08 08:42:56 -05:00
InverseBot 0ffbc13376 (js/css) Update generated files 2017-03-08 01:57:09 -05:00
Francis Lachapelle a02fa44dc7 (js) Fix SCAYT automatic language selection 2017-03-07 14:23:42 -05:00
Francis Lachapelle 682f699e2f Fix Welsh's locale 2017-03-07 14:20:51 -05:00
Ludovic Marcotte f3b098da75 Updated NEWS 2017-03-07 10:48:20 -05:00
Ludovic Marcotte 6a963bf84b (fix) remove attendees that have the same identity of the organizer (fixes #3905) 2017-03-07 10:45:44 -05:00
Francis Lachapelle 270ff1bd29 (js) Fix saving draft outside Mail module
Fixes #4071
2017-03-07 10:26:10 -05:00
InverseBot 74c2926bca (js/css) Update generated files 2017-03-04 01:34:40 -05:00
Francis Lachapelle 75aa6e90a2 (js) Fix handling of attachments in mail editor
Fixes #4058, #4063
2017-03-03 15:36:52 -05:00
Francis Lachapelle 3c35c16bf3 (html) Display year in day and week views 2017-03-03 15:01:00 -05:00
Ludovic Marcotte e95e8e9eac Updated NEWS 2017-03-03 14:15:27 -05:00
Ludovic Marcotte 588ec2b005 (fix) fixed handling of exdates and proper intersection for fbinfo (fixes #4051) 2017-03-03 14:13:25 -05:00
Francis Lachapelle 0627c2f58b (html) Constrain reminder to a positive number 2017-03-03 12:06:33 -05:00
Francis Lachapelle f6ed816243 (html) Constrain reminder to a positive number 2017-03-03 12:05:34 -05:00
Francis Lachapelle 25430a8128 Fix handling of contact organizations
Fixes #4028
2017-03-03 10:35:50 -05:00
Ludovic Marcotte 79a0d5e133 (fix) handle broken CalDAV clients sending bogus SENT-BY (fixes #3992) 2017-03-03 08:47:59 -05:00
InverseBot 018b7b7ab9 (js/css) Update generated files 2017-03-03 01:24:59 -05:00
Francis Lachapelle c8539dffa1 (js) Limit http error interceptor to JSON request 2017-03-02 15:48:31 -05:00
InverseBot c995c6e9d7 (js/css) Update generated files 2017-03-02 01:27:34 -05:00
Francis Lachapelle 8322d318aa Expose default value of SOGoMailAutoSave
Fixes #4053
2017-03-01 15:14:09 -05:00
Ludovic Marcotte 4d88eab13b Updated NEWS 2017-03-01 11:36:15 -05:00
Francis Lachapelle a3d7ae3a6b (js) Improve CAS handling 2017-03-01 11:15:25 -05:00
Ludovic Marcotte a29ced853a (js/css) Update generated files 2017-03-01 11:00:17 -05:00
Ludovic Marcotte 5047aed6ed (fix) more CAS fixes 2017-03-01 10:51:01 -05:00
Ludovic Marcotte 3c46a6ef14 (js/css) Update generated files 2017-03-01 09:49:36 -05:00
Ludovic Marcotte af3a35169a (fix) first pass at CAS XHR issue 2017-03-01 09:37:37 -05:00
InverseBot 6b471994ef (js/css) Update generated files 2017-03-01 01:23:28 -05:00
Francis Lachapelle 23ff62a9e0 (js) Improve event editor
- fixed form validity check;
- fixed alarm restoration after a reset;
- fixed recurrence rules check.
2017-02-28 16:13:58 -05:00
Francis Lachapelle 2a820bd780 (css) Improve display of event editor 2017-02-28 08:36:27 -05:00
InverseBot 125178e526 (js/css) Update generated files 2017-02-28 01:23:07 -05:00
Francis Lachapelle e1979976a6 (js) Month day(s) of monthly repeat must be set 2017-02-27 16:04:49 -05:00
Francis Lachapelle d87cf6980a (css) Improve display of recurrence editor 2017-02-27 16:03:45 -05:00
Francis Lachapelle dfce966e79 (js) Calendar week days must be set to save prefs 2017-02-27 12:55:15 -05:00
Francis Lachapelle 4002650748 (js) Expose model validity in sg-toggle-grid 2017-02-27 10:48:40 -05:00
InverseBot 0fa8cbf9cb (js/css) Update generated files 2017-02-23 01:24:05 -05:00
Francis Lachapelle 7a4dbcb364 (js) Update children paths when renaming a mailbox
Fixes #4046
2017-02-22 23:07:26 -05:00
Ludovic Marcotte 784503bdbc (fix) minor fixes in tools 2017-02-22 11:00:01 -05:00
Ludovic Marcotte 91b32faac2 Updated NEWS 2017-02-21 10:14:58 -05:00
Ludovic Marcotte f24d9ae389 (fix) safety checks, fixed remove ALL and added add ALL 2017-02-21 10:12:55 -05:00
Ludovic Marcotte b501014935 (feat) new sogo-tool manage-acl feature to get/add/remove ACLs from GCS folders 2017-02-20 18:57:46 -05:00
Ludovic Marcotte cc52e82524 (feat) added delete capability to sogo-tool checkup 2017-02-20 13:37:23 -05:00
Ludovic Marcotte fe42180bc0 (fix) set the memcache retry timeout to 5 seconds 2017-02-20 10:35:08 -05:00
Ludovic Marcotte 7f67e90c53 (fix) enable tcp_nodelay for memcache 2017-02-20 10:34:54 -05:00
InverseBot bf001b1af6 (js/css) Update generated files 2017-02-20 01:22:37 -05:00
Francis Lachapelle 3c65973cd5 (css) Hide fab button when printing
Fixes #4038
2017-02-19 21:57:27 -05:00
Francis Lachapelle 48b2008da4 (js) Localize mailbox names everywhere
Fixes #4041
2017-02-19 21:13:44 -05:00
InverseBot fd13fd632c (js/css) Update generated files 2017-02-18 01:21:42 -05:00
Francis Lachapelle b1e8f30138 (js) Localized inbox label
Fixes #4040
2017-02-17 21:22:10 -05:00
Ludovic Marcotte fc68709956 Updated NEWS 2017-02-17 15:19:37 -05:00
Francis Lachapelle 06238a39b1 (js) Fix fcn call when removing contact category
Fixes #4039
2017-02-17 11:01:42 -05:00
Francis Lachapelle 9f84162c5d (css) Fix ACL editor in Admin module for Safari
Fixes #4036
2017-02-15 23:11:34 -05:00
InverseBot 6ffc9a3552 (js/css) Update generated files 2017-02-15 01:29:55 -05:00
Ludovic Marcotte 3894d6f9fa Release preparation 2017-02-14 08:38:39 -05:00
InverseBot 07720563b9 (js/css) Update generated files 2017-02-14 01:16:42 -05:00
Francis Lachapelle 5ceafa5005 (js) Localize mail, phone, url and address types
Fixes #4030
2017-02-13 22:52:03 -05:00
Ludovic Marcotte 24da483e2a Updated NEWS 2017-02-09 14:42:42 -05:00
Ludovic Marcotte 9434e3882e (feat) new sogo-tool checkup command to make sure user's data is sane 2017-02-09 14:39:24 -05:00
Ludovic Marcotte 7d1dd4ec76 Updated NEWS 2017-02-09 08:57:56 -05:00
Ludovic Marcotte 54eedb3363 (fix) moved bcc handling code to the generic mail sending method 2017-02-09 08:56:02 -05:00
InverseBot e9ea104a94 (js/css) Update generated files 2017-02-09 01:29:10 -05:00
InverseBot 99277421a1 (js/css) Update generated files 2017-02-08 01:27:36 -05:00
Ludovic Marcotte 3d5c0be441 Updated NEWS 2017-02-03 15:27:39 -05:00
Ludovic Marcotte dd8cccdafc (fix) correctly handle Canceled appointments 2017-02-03 15:24:42 -05:00
InverseBot dcfed38fc7 (js/css) Update generated files 2017-02-03 01:25:57 -05:00
InverseBot b58ec19625 (js/css) Update generated files 2017-02-02 01:24:16 -05:00
Francis Lachapelle d90533399d (css) Keep the fab button visible 2017-02-01 21:33:17 -05:00
Ludovic Marcotte 4db1f8185a Updated NEWS 2017-02-01 13:06:03 -05:00
Ludovic Marcotte 50d8975f9d (fix) improve EAS parameters parsing (fixes #4003) 2017-02-01 13:03:27 -05:00
Francis Lachapelle b412788e39 Make sure to refer to filenames when executing zip
Fixes #4015
2017-02-01 11:56:44 -05:00
Ludovic Marcotte 15b277fa8e (fix) cache sogo_folder_info records and avoid phantom subscriptions (fixes #4010) 2017-01-31 15:59:58 -05:00
InverseBot d159b191a6 (js/css) Update generated files 2017-01-31 01:12:42 -05:00
Francis Lachapelle 539a6c3beb Fix public URL with special characters
Fixes #3993
2017-01-30 21:56:33 -05:00
Francis Lachapelle abccdd304f (js) Ignore mouse events in scrollbars of Month
Firefox is bubbling the mouse down event on scrollbars so it has to be
ignored for proper drag'n'drop.

Fixes #3990.
2017-01-30 15:52:07 -05:00
Francis Lachapelle 4143a23afd Add Hebrew translation (cont'd) 2017-01-30 07:51:36 -05:00
Francis Lachapelle a020286780 Merge pull request #232 from rfrei/patch-1
Allow write to multiple contacts using 'to', 'cc' or 'bcc'.

Fixes #3548.
2017-01-30 07:46:54 -05:00
Steffen Müller 1b264ef6ba Change Strings according to RFC 5322
correction: for translations the strings in English.lproj should better be equal
2017-01-28 17:53:14 +01:00
Steffen Müller ef4e311a5a Change Strings according to RFC 5322 2017-01-28 17:53:05 +01:00
Steffen Müller 1d8caa4297 Change Strings according to RFC 5322 2017-01-28 17:22:14 +01:00
InverseBot 0500499d91 (js/css) Update generated files 2017-01-28 01:10:29 -05:00
Francis Lachapelle d289a441bb Fix condition when enabling Vacation message 2017-01-27 15:57:43 -05:00
Francis Lachapelle fcfbc50139 Add Hebrew translation (cont'd) 2017-01-27 12:58:31 -05:00
Francis Lachapelle 88bc1294cd (js) Fix saving the preferences with Mail disabled 2017-01-27 12:40:36 -05:00
Francis Lachapelle ac127a375f Improve ACLs handling of inactive users (cont'd) 2017-01-27 12:22:22 -05:00
Steffen Müller f90b2efadb simpler version 2017-01-27 16:52:58 +01:00
Steffen Müller c9a50aa057 write using 'to', 'cc' or 'bcc' with string parameter
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-27 16:41:34 +01:00
Steffen Müller 621adb38c2 write using 'to', 'cc' or 'bcc' with string parameter
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-27 16:37:13 +01:00
InverseBot 872afaec32 (js/css) Update generated files 2017-01-27 01:10:15 -05:00
Francis Lachapelle 892e6d6eb2 Add Hebrew translation 2017-01-26 21:40:52 -05:00
Steffen Müller ed62670a1a write using 'to', 'cc' or 'bcc'
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-26 19:27:13 +01:00
Francis Lachapelle 7a6df34cb6 Update ChangeLog 2017-01-26 13:18:17 -05:00
Francis Lachapelle 556460982d Preparation for release 3.2.6a 2017-01-26 13:17:52 -05:00
Francis Lachapelle 2beb3dca6d (js/css) Update generated files 2017-01-26 13:16:19 -05:00
Francis Lachapelle d14b0b0b5e (js) Improve ACLs handling of inactive users 2017-01-26 12:48:21 -05:00
Steffen Müller 8efd01d55e write using 'to', 'cc' or 'bcc'
write to multiple selected contacts using 'to', 'cc' or 'bcc'
Feauture Request #3548
2017-01-26 18:29:07 +01:00
Francis Lachapelle 831c1bc980 Revert "(fix) properly honor "include in freebusy"
This reverts commit eed5679068.
2017-01-26 11:52:58 -05:00
Francis Lachapelle d277f2fe0f Update ChangeLog 2017-01-23 14:58:02 -05:00
Francis Lachapelle 0b9ca225d0 (css) Update default theme 2017-01-23 14:58:02 -05:00
Francis Lachapelle 04c256ab6c Preparation for release 3.2.6 2017-01-23 14:57:47 -05:00
InverseBot 3cbeba32d9 (js/css) Update generated files 2017-01-24 01:15:53 -05:00
Francis Lachapelle 1825b167dc (css,js) Update md to v1.1.1-master-2c9a5cc 2017-01-23 09:55:44 -05:00
Francis Lachapelle 214ce5ef86 (i18n) Update translations 2017-01-23 09:50:35 -05:00
Ludovic Marcotte 927f0c3220 Updated NEWS 2017-01-23 08:55:33 -05:00
Ludovic Marcotte 227cf582d9 (fix) touch objects when server-side changes occured 2017-01-23 08:53:41 -05:00
InverseBot 8cdc435945 (js/css) Update generated files 2017-01-21 01:28:13 -05:00
Francis Lachapelle 3efe0e8098 Add support for date extension of Sieve
Fixes #1530, #1949
2017-01-20 11:08:24 -05:00
Ludovic Marcotte d38d42b83a (fix) use login in domain 2017-01-20 09:25:02 -05:00
InverseBot 1f3a89b984 (js/css) Update generated files 2017-01-20 01:27:56 -05:00
Francis Lachapelle 0dea9c226d Allow to select multiple files when uploading
Fixes #3999
2017-01-19 15:41:21 -05:00
Francis Lachapelle db1cc24c20 (css) Improve display of HTML CKEditor 2017-01-19 14:47:11 -05:00
Francis Lachapelle d7d88e2620 (js) Compose new message in a popup window 2017-01-19 12:23:55 -05:00
Francis Lachapelle 4fca484ed0 Improve error handling in SOGoWebAppointmentFolder 2017-01-19 10:31:03 -05:00
Francis Lachapelle fcb79dc14b Improve error handling in MSExchangeFreeBusy class 2017-01-19 10:17:17 -05:00
Francis Lachapelle 41dbb88b64 (js) Expandable mail editor
Added "autogrow" plugin for CKEditor.
2017-01-19 07:05:52 -05:00
InverseBot bb97b57ad7 (js/css) Update generated files 2017-01-19 01:28:13 -05:00
Ludovic Marcotte 5300d4185d (fix) improve doc around SOGoTimeZone (fixes #3995) 2017-01-18 16:17:12 -05:00
Francis Lachapelle 26b69d25ee (js) Fix opening message in popup window 2017-01-18 15:03:29 -05:00
Ludovic Marcotte a3c056ea84 (fix) deep-search for text/calendar parts 2017-01-17 15:12:29 -05:00
Ludovic Marcotte e4b2539b04 (fix) strip attendees with no email and don't send IMIP when it's Outlook the EAS client 2017-01-17 12:40:41 -05:00
Francis Lachapelle fcb6542d06 (i18n) Update translations 2017-01-17 11:47:43 -05:00
Francis Lachapelle 174fcd5c31 (i18n) Update translations 2017-01-17 08:53:52 -05:00
InverseBot 2f6c5148aa (js/css) Update generated files 2017-01-17 01:30:41 -05:00
Francis Lachapelle 936b21b8c0 (css) Fix glitches in Month view with Firefox 2017-01-16 16:30:24 -05:00
Francis Lachapelle 5f2a6c53c4 (js) Fix pasting images in CKEditor
Fixes #3986
2017-01-16 15:31:12 -05:00
Francis Lachapelle ba12c14a1d (js) Update CKEditor to version 4.6.2
- Add Upload Image plugin

Fixes #3986
2017-01-13 16:11:10 -05:00
Ludovic Marcotte 4158f7555e Updated NEWS 2017-01-13 13:19:43 -05:00
Ludovic Marcotte 6e0f5b2254 (fix) return if not content is there, to avoid random crash 2017-01-13 13:16:01 -05:00
Francis Lachapelle 4a21a02f98 Fix rendering of forwarded HTML message with img
Fixes #3981 (cont'd)
2017-01-13 12:23:38 -05:00
Ludovic Marcotte 9d7d2575d3 (ix) remove alarms in IMIP responses (fixes #3925) 2017-01-12 15:23:09 -05:00
InverseBot 905859053c (js/css) Update generated files 2017-01-12 01:31:09 -05:00
Francis Lachapelle e5d0b0b0ca Fix rendering of forwarded HTML message with img
Fixes #3981 (partially)
2017-01-11 16:08:56 -05:00
Francis Lachapelle 589827a414 (html) Show locale codes beside language names 2017-01-11 14:20:43 -05:00
Francis Lachapelle 42ee981613 (js) Update Angular to branch 1.6.x 2017-01-11 14:20:43 -05:00
Francis Lachapelle 5985262e0f Improve WebDAV Python lib for integration tests 2017-01-11 14:20:42 -05:00
Francis Lachapelle c36fcd2902 Improve debugging output of recurrence calculator 2017-01-11 14:20:42 -05:00
Francis Lachapelle bce09f413f Update NEWS file 2017-01-11 14:20:42 -05:00
Francis Lachapelle 9477c1af16 (html) Precise EAS beside "Synchronize" option 2017-01-11 14:20:42 -05:00
InverseBot 8011d9093e (js/css) Update generated files 2017-01-11 01:26:52 -05:00
Francis Lachapelle 37334db0e3 Update ChangeLog 2017-01-10 09:42:57 -05:00
Francis Lachapelle 6637bde56d Preparation for release 3.2.5 2017-01-10 09:42:09 -05:00
Francis Lachapelle e27efc4d3a (css) Update default theme 2017-01-10 09:37:05 -05:00
Francis Lachapelle ff7b9a3725 (js/css) Update generated files 2017-01-10 09:33:43 -05:00
Francis Lachapelle 36c7ffcc3c (css,js) Update md to v1.1.1-master-64b2621 2017-01-10 09:16:04 -05:00
InverseBot 3912d2ab3e (js/css) Update generated files 2017-01-10 02:12:03 -05:00
Ludovic Marcotte 5e775ea4ce (fix) some more memory info 2017-01-09 16:09:09 -05:00
Ludovic Marcotte 841fdb96cc (fix) be a bit more verbose about memory usage 2017-01-09 16:03:32 -05:00
Francis Lachapelle 51ff746595 (js) Update CKEditor to version 4.6.1 2017-01-06 20:49:42 -05:00
Francis Lachapelle ef1f5a948f (i18n) Update translations 2017-01-06 20:34:37 -05:00
Francis Lachapelle 3560f0486e (js) Fix hotkeys with an active dialog in Mailer
Fixes #3983
2017-01-06 18:26:12 -05:00
Francis Lachapelle 327ebf00a4 Fix public URLs to Calendars
Fixes #3974
2017-01-06 16:49:00 -05:00
InverseBot abb1e1b447 (js/css) Update generated files 2017-01-07 01:28:44 -05:00
Francis Lachapelle 818233535f Improve error messages around draft attachments
(cont'd)
2017-01-06 16:17:05 -05:00
Francis Lachapelle 65e3fe978c Minor code cleanup 2017-01-06 16:15:26 -05:00
Francis Lachapelle 0216f19e55 Improve Installation Guide 2017-01-06 16:14:44 -05:00
Francis Lachapelle 8404de758b Improve error messages around draft attachments 2017-01-06 16:12:42 -05:00
Francis Lachapelle 5ec7ad54bb Fix error handling when draft is too big 2017-01-06 15:45:30 -05:00
Ludovic Marcotte be8e1373ea Updated NEWS 2017-01-06 16:01:52 -05:00
Ludovic Marcotte 9fbc84158a (fix) handle sha512-crypt with rounds 2017-01-06 15:52:19 -05:00
Ludovic Marcotte 071c1032c1 Updated NEWS 2017-01-06 14:34:43 -05:00
Ludovic Marcotte af8baf41cb (fix) correctly handle all identities during IMIP status update 2017-01-06 14:32:45 -05:00
Ludovic Marcotte 0b7ddf7ca4 (fix) small optimization over previous commit 2017-01-06 14:29:41 -05:00
Ludovic Marcotte 942ddcabe4 (fix) handle all identities during IMIP REPLY processing 2017-01-06 14:23:52 -05:00
Ludovic Marcotte bdd8254e02 (fix) make sure we compare the organizer's email only 2017-01-06 11:03:59 -05:00
Ludovic Marcotte ce0575517d (fix) make sure to bump LAST-MODIFIED to trigger all auto-scheduling code 2017-01-06 09:54:02 -05:00
Francis Lachapelle ea7934a73c Fix saving of inactive calendars
Fixes #3862, #3980
2017-01-06 06:42:12 -05:00
InverseBot 02fc147624 (js/css) Update generated files 2017-01-06 02:11:11 -05:00
Francis Lachapelle 02a1ad48fc (js) Fix computation of week number
Fixes #3973, 3976
2017-01-05 12:00:55 -05:00
Ludovic Marcotte e7e1283fb3 (fix) disabled bias computation for now 2017-01-05 09:27:16 -05:00
InverseBot d5e04be1df (js/css) Update generated files 2017-01-01 01:20:37 -05:00
Ludovic Marcotte e2ec8af0db Updated NEWS 2016-12-30 12:29:09 -05:00
Ludovic Marcotte 477c06a7ff (fix) fix events in floating time during CalDAV's PUT operation (fixes #2865) 2016-12-30 12:26:31 -05:00
Ludovic Marcotte 479b534857 (fix) properly save email alarms in the db (fixes #3949) 2016-12-30 10:31:29 -05:00
Ludovic Marcotte f6bcf26793 Updated NEWS 2016-12-30 10:00:58 -05:00
Ludovic Marcotte cdf6aaa53e (fix) provide correct error response to EAS client when sending big mails (fixes #3956) 2016-12-30 09:58:51 -05:00
Ludovic Marcotte 1a9b20519e Updated NEWS 2016-12-29 16:23:07 -05:00
Ludovic Marcotte 4f211678e9 (fix) handle semicolon in value during LDIF import (fixes #1760) 2016-12-29 16:21:30 -05:00
Ludovic Marcotte e578787acd Updated NEWS 2016-12-29 14:37:04 -05:00
Ludovic Marcotte 239dffa391 (fix) handle URI in vCard photos (fixes #2683) 2016-12-29 14:35:06 -05:00
Ludovic Marcotte 6cd3d90410 Updated NEWS 2016-12-29 14:14:39 -05:00
Ludovic Marcotte 93dfbc5a94 (feat) added photo support for LDIF import (fixes #1084) 2016-12-29 14:12:45 -05:00
Ludovic Marcotte 896f57f634 Updated NEWS 2016-12-29 10:53:44 -05:00
Ludovic Marcotte f48ab310d6 (fix) add support for "other" addresses (fixes #3966) 2016-12-29 10:52:32 -05:00
Ludovic Marcotte 5bc21e4f53 (fix) avoid trying to parse empty request (fixes #3969) 2016-12-29 09:55:20 -05:00
Ludovic Marcotte 8296123650 Updated NEWS 2016-12-28 10:25:31 -05:00
Ludovic Marcotte 2cebee42b7 (feat) added new SOGoMaximumMessageSizeLimit config parameter (fixes #3510)
Conflicts:

	SoObjects/Mailer/SOGoDraftObject.m
2016-12-28 10:23:19 -05:00
Ludovic Marcotte 7c7440c988 Updated NEWS 2016-12-23 11:38:39 -05:00
Ludovic Marcotte eed5679068 (fix) properly honor "include in freebusy" (fixes #3354) 2016-12-23 11:36:44 -05:00
Ludovic Marcotte f1dbb88303 Updated NEWS 2016-12-23 10:22:07 -05:00
Ludovic Marcotte 9cb6772ae8 (fix) do not decode from hex the event's UID (fixes #3965) 2016-12-23 10:19:46 -05:00
Ludovic Marcotte dceab8fd2a Updated NEWS 2016-12-23 10:06:15 -05:00
Ludovic Marcotte 7197b7eb41 (fix) handle delegation scenario with no SENT-BY set (fixes #3368) 2016-12-23 10:04:43 -05:00
InverseBot 18b502c39c (js/css) Update generated files 2016-12-23 02:10:39 -05:00
Ludovic Marcotte 94fc5d17db (fix) also use the filter when doing DN lookups (fixes #2253) 2016-12-22 14:26:27 -05:00
Ludovic Marcotte 8c075d2e1b (fix) comment out vars too 2016-12-22 09:41:39 -05:00
Ludovic Marcotte 278aeef864 (fix) disabled IMIP force sending for Lightning (fixes #3274) 2016-12-22 08:55:12 -05:00
Ludovic Marcotte ef69344a59 Updated NEWS 2016-12-21 11:45:41 -05:00
Ludovic Marcotte 457fccd5ac (fix) append .ics extension if not present when importing events (fixes #2308) 2016-12-21 11:43:08 -05:00
Ludovic Marcotte 1da36a3ef9 (fix) always force save events creation over EAS (fixes #3958) 2016-12-21 10:47:33 -05:00
Francis Lachapelle 7327ec21b2 Avoid duplicate emails in LDAP-based address book
Fixes #3941
2016-12-21 10:37:04 -05:00
Ludovic Marcotte 94c522ea5c Updated NEWS 2016-12-21 08:50:38 -05:00
Ludovic Marcotte 5c0229466e (feat) handle alarms for tasks (fixes #3964) 2016-12-21 08:49:05 -05:00
Ludovic Marcotte eb6d234c4b Updated NEWS 2016-12-20 13:17:19 -05:00
Ludovic Marcotte 06903f8376 (fix) use the source's domain if none is defined (fixes #3523) 2016-12-20 13:15:15 -05:00
Francis Lachapelle 596c4bb4c2 (js) Fix attached links in task viewer
Fixes #3963
2016-12-20 10:44:43 -05:00
Ludovic Marcotte 3d16283d3c (fix) avoid double encoding (fixes #3960) 2016-12-20 08:56:13 -05:00
InverseBot 31d2db51ad (js/css) Update generated files 2016-12-20 01:24:11 -05:00
Ludovic Marcotte abd0c0a744 (fix) sage-guard against empty rrule 2016-12-19 15:01:31 -05:00
Francis Lachapelle 1375237697 (js) Don't allow to create a list in a remote AB 2016-12-19 12:07:17 -05:00
Francis Lachapelle 4c78d81bf7 Formatting & Comments 2016-12-19 11:15:35 -05:00
Francis Lachapelle 2e9168080c (js) Fix freebusy initialization in event editor 2016-12-19 11:05:48 -05:00
Francis Lachapelle 1eb378c956 (js) Fix display of auto-reply (vacation) message
Fixes #3940
2016-12-19 10:25:04 -05:00
Francis Lachapelle e739ed46a3 (js) Fix saving monthly BYDAY recurrence
Fixes #3948
2016-12-19 09:51:09 -05:00
Francis Lachapelle 93f559a0df Remove unnecessary div in UIxTopnavToolbar.wox 2016-12-19 09:46:58 -05:00
InverseBot 13a4398c4d (js/css) Update generated files 2016-12-17 01:24:00 -05:00
Ludovic Marcotte 462d274497 Updated NEWS 2016-12-16 15:53:12 -05:00
Ludovic Marcotte ab1c699bc7 (feat) better support for RFC 6638 (schedule-agent) (fixes #2599) 2016-12-16 15:51:19 -05:00
Ludovic Marcotte 9882052e81 Updated NEWS 2016-12-16 10:12:40 -05:00
Ludovic Marcotte 3adbef5aa4 (fix) 30 mins offset in FB 2016-12-16 10:08:04 -05:00
Ludovic Marcotte 5ecf917e6b (fix) return a 404 for public user 2016-12-16 09:07:55 -05:00
InverseBot a02642cad9 (js/css) Update generated files 2016-12-16 01:09:03 -05:00
Ludovic Marcotte 92ba421dd1 Updated NEWS 2016-12-15 14:24:08 -05:00
Ludovic Marcotte ea940e645e (fix) return login page for unknown users (fixes #2135) 2016-12-15 14:22:26 -05:00
Francis Lachapelle 651c0fdf14 Load photos of LDAP-based address books in listing
Fixes #3942
2016-12-15 10:19:47 -05:00
InverseBot 15a3bf48d9 (js/css) Update generated files 2016-12-15 01:22:53 -05:00
Ludovic Marcotte 8493701408 Updated NEWS 2016-12-14 21:22:45 -05:00
Ludovic Marcotte f0085ef43e (fix) correctly block if fail count is within interval (fixes #2850) 2016-12-14 21:20:29 -05:00
Francis Lachapelle e0108088ee (js) Rename buttons of alarm toast
Fixes #3945
2016-12-14 16:39:21 -05:00
Francis Lachapelle 5591b9d423 (js) Switch on "remember username" when necessary 2016-12-14 16:33:21 -05:00
Ludovic Marcotte ef96c21334 Updated NEWS 2016-12-14 13:46:27 -05:00
Ludovic Marcotte d8eae96d63 (fix) properly skip folders we don't want (fixes #3943) 2016-12-14 13:42:22 -05:00
InverseBot f6acc3e984 (js/css) Update generated files 2016-12-11 01:19:01 -05:00
Ludovic Marcotte 340ddf0ae6 (fix) make sure we safely escape all chars 2016-12-09 10:45:44 -05:00
Ludovic Marcotte b0fcaeef86 (fix) removed old code 2016-12-09 10:32:42 -05:00
Ludovic Marcotte ec19a1290d (fix) use the organizer's alarm by default when accepting IMIP messages (fixes #3934) 2016-12-09 09:47:48 -05:00
InverseBot 384f1cb53f (js/css) Update generated files 2016-12-09 01:17:34 -05:00
Francis Lachapelle d0e0d5300a (js) Fix ordering of calendars
Fixes #3931
2016-12-08 10:17:25 -05:00
InverseBot 4b2b3693c5 (js/css) Update generated files 2016-12-08 01:18:39 -05:00
Francis Lachapelle 011fae8a65 Download attachments of a message as a zip archive 2016-12-07 14:38:33 -05:00
Ludovic Marcotte 2a2ebd553e (test) handle sanitization before passing data to libxml 2016-12-06 14:05:27 -05:00
Francis Lachapelle 0038e4bc60 (js) Disable HTML entities in CKEditor 2016-12-06 10:08:02 -05:00
InverseBot e053f12e78 (js/css) Update generated files 2016-12-06 01:17:41 -05:00
Francis Lachapelle c663f7ab4c Prevent using localhost on auxiliary IMAP accounts 2016-12-05 16:12:16 -05:00
Ludovic Marcotte 68ddcd7045 (fix) prevent using localhost on additional IMAP accounts 2016-12-05 14:51:33 -05:00
InverseBot ffd69337f6 (js/css) Update generated files 2016-12-03 02:04:11 -05:00
Francis Lachapelle ba5bd65ea3 Fix support for SOGoSieveFolderEncoding defaults
Cont'd. Fixes #3904
2016-12-02 17:38:33 -05:00
Francis Lachapelle 6ce64a9a27 (js) Fix sorting after renaming an AddressBook 2016-12-02 14:48:59 -05:00
Ludovic Marcotte 41701cc94c (fix) properly set interval for monthly recurring events using EAS 2016-12-02 09:21:18 -05:00
Ludovic Marcotte 56d7f634a0 (fix) avoid compiler warning 2016-12-02 08:48:26 -05:00
InverseBot 80f67785c3 (js/css) Update generated files 2016-12-02 01:29:36 -05:00
Francis Lachapelle 29dfadfe75 (css) Update default theme 2016-12-01 17:47:29 -05:00
Francis Lachapelle fb743d6381 Update Developer's Guide 2016-12-01 16:01:45 -05:00
Francis Lachapelle 203dcf1d05 (js) Improve sgAvatarImage (cont'd) 2016-12-01 15:42:28 -05:00
Francis Lachapelle 0d95267fe5 Fix ACLs management of folders in Administration
The active (super) user was not able to add herself to the ACLs of a
different user because we were removing the active user from the users
search instead of removing the folder's owner.
2016-12-01 15:40:38 -05:00
Francis Lachapelle e997923c31 (html) Fix sidenav breakpoint in Admin module 2016-12-01 15:32:24 -05:00
Francis Lachapelle 277c6e901e Update ChangeLog 2016-12-01 12:02:23 -05:00
Francis Lachapelle 2c24901803 (js/css) Update generated files 2016-12-01 12:01:50 -05:00
Francis Lachapelle 8f90aa96fe (css,js) Update md to v1.1.1-master-b8357dc 2016-12-01 12:00:00 -05:00
Francis Lachapelle ee5b60c544 Preparation for release 3.2.4 2016-12-01 11:59:16 -05:00
Francis Lachapelle d2b94eba09 (js) Fix detection of session expiration 2016-12-01 11:56:07 -05:00
Francis Lachapelle c9467e1ce3 Validate custom subject for vacation auto-reply 2016-12-01 11:21:59 -05:00
Francis Lachapelle b4e9b7b60c (css) Fix sidenav background color of Preferences 2016-12-01 11:14:38 -05:00
Francis Lachapelle 66710f1b17 (i18n) Update translations 2016-12-01 11:07:28 -05:00
Francis Lachapelle a61ea24cdb (obj-c) Indentation 2016-12-01 10:28:26 -05:00
Francis Lachapelle 3e448d2c2c New sogo-tool cleanup user feature (cont'd) 2016-12-01 10:27:22 -05:00
Ludovic Marcotte 9aa00d049d Updated NEWS 2016-12-01 09:42:03 -05:00
Ludovic Marcotte fdea54f5e7 (fix) properly escape all GAL responses (fixes #3923) 2016-12-01 09:40:24 -05:00
InverseBot 3c098ceca5 (js/css) Update generated files 2016-12-01 01:18:40 -05:00
Francis Lachapelle f7dd835f92 Fix mail attribute when importing an LDIF file
Fixes #3878
2016-11-30 16:06:09 -05:00
Francis Lachapelle 7705c11cf7 New sogo-tool cleanup user feature 2016-11-30 15:32:29 -05:00
Francis Lachapelle 52cdb71d1f Add sort by start date for the tasks list
Fixes #3840
2016-11-30 12:13:48 -05:00
Francis Lachapelle a1746cd386 (css) Fix display of tabs with oversized content 2016-11-30 12:09:11 -05:00
InverseBot cd08ab81f1 (js/css) Update generated files 2016-11-30 02:47:47 -05:00
Francis Lachapelle d293fe79ed Add handling of BYSETPOS for BYDAY in repeat rule 2016-11-29 17:47:14 -05:00
Francis Lachapelle 6f732ba535 Fix MSExchangeFreeBusySOAPRequest.wod 2016-11-29 16:14:42 -05:00
Francis Lachapelle b27c868271 Fix freebusy data fetching of MS Exchange contacts 2016-11-29 15:48:15 -05:00
InverseBot e0b0a1d783 (js/css) Update generated files 2016-11-29 03:13:53 -05:00
Francis Lachapelle e059a6043e (js) Fix possible cross-origin exception
When SOGo is launched from an external link, either using a different
"target" or using window.open(), the Mail composer could throw a
JavaScript exception when trying to save or send a message that would
completely stop the operation.

Fixes #3900
2016-11-28 15:36:03 -05:00
Francis Lachapelle e253f5735d (js) Don't test pristine state of Message composer 2016-11-28 11:45:09 -05:00
Francis Lachapelle 328d67ec3a Improve sort validation in Contacts module 2016-11-28 10:33:38 -05:00
Francis Lachapelle c3376a4ddf Fix some compilation warnings 2016-11-28 10:14:23 -05:00
Francis Lachapelle 220fb3d607 (js) Update alarms after dragging an event 2016-11-28 09:37:31 -05:00
InverseBot fb873fcae9 (js/css) Update generated files 2016-11-26 02:52:49 -05:00
Ludovic Marcotte d2e03386d2 (fix) use GMT + adjust bias when querying Exchange's FB info 2016-11-25 15:14:24 -05:00
900 changed files with 41846 additions and 23189 deletions

No files matched your search

-2
View File
@@ -19,8 +19,6 @@ UI/WebServerResources/.bowerrc
UI/WebServerResources/.sass-cache/
UI/WebServerResources/bower_components/
UI/WebServerResources/css/
UI/WebServerResources/css/styles.css
UI/WebServerResources/css/styles.css.map
UI/WebServerResources/js/*.js
UI/WebServerResources/js/*.js.map
UI/WebServerResources/js/vendor/*.js
+11
View File
@@ -15,6 +15,7 @@ trans.es_ES = UI/MailerUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/MailerUI/Basque.lproj/Localizable.strings
trans.fi = UI/MailerUI/Finnish.lproj/Localizable.strings
trans.fr = UI/MailerUI/French.lproj/Localizable.strings
trans.he = UI/MailerUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/MailerUI/Croatian.lproj/Localizable.strings
trans.hu = UI/MailerUI/Hungarian.lproj/Localizable.strings
trans.is = UI/MailerUI/Icelandic.lproj/Localizable.strings
@@ -50,6 +51,7 @@ trans.es_ES = UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/PreferencesUI/Basque.lproj/Localizable.strings
trans.fi = UI/PreferencesUI/Finnish.lproj/Localizable.strings
trans.fr = UI/PreferencesUI/French.lproj/Localizable.strings
trans.he = UI/PreferencesUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/PreferencesUI/Croatian.lproj/Localizable.strings
trans.hu = UI/PreferencesUI/Hungarian.lproj/Localizable.strings
trans.is = UI/PreferencesUI/Icelandic.lproj/Localizable.strings
@@ -85,6 +87,7 @@ trans.es_ES = UI/Scheduler/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/Scheduler/Basque.lproj/Localizable.strings
trans.fi = UI/Scheduler/Finnish.lproj/Localizable.strings
trans.fr = UI/Scheduler/French.lproj/Localizable.strings
trans.he = UI/Scheduler/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/Scheduler/Croatian.lproj/Localizable.strings
trans.hu = UI/Scheduler/Hungarian.lproj/Localizable.strings
trans.is = UI/Scheduler/Icelandic.lproj/Localizable.strings
@@ -120,6 +123,7 @@ trans.es_ES = UI/Contacts/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/Contacts/Basque.lproj/Localizable.strings
trans.fi = UI/Contacts/Finnish.lproj/Localizable.strings
trans.fr = UI/Contacts/French.lproj/Localizable.strings
trans.he = UI/Contacts/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/Contacts/Croatian.lproj/Localizable.strings
trans.hu = UI/Contacts/Hungarian.lproj/Localizable.strings
trans.is = UI/Contacts/Icelandic.lproj/Localizable.strings
@@ -155,6 +159,7 @@ trans.es_ES = UI/MainUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/MainUI/Basque.lproj/Localizable.strings
trans.fi = UI/MainUI/Finnish.lproj/Localizable.strings
trans.fr = UI/MainUI/French.lproj/Localizable.strings
trans.he = UI/MainUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/MainUI/Croatian.lproj/Localizable.strings
trans.hu = UI/MainUI/Hungarian.lproj/Localizable.strings
trans.is = UI/MainUI/Icelandic.lproj/Localizable.strings
@@ -190,6 +195,7 @@ trans.es_ES = UI/Common/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/Common/Basque.lproj/Localizable.strings
trans.fi = UI/Common/Finnish.lproj/Localizable.strings
trans.fr = UI/Common/French.lproj/Localizable.strings
trans.he = UI/Common/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/Common/Croatian.lproj/Localizable.strings
trans.hu = UI/Common/Hungarian.lproj/Localizable.strings
trans.is = UI/Common/Icelandic.lproj/Localizable.strings
@@ -225,6 +231,7 @@ trans.es_ES = UI/AdministrationUI/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/AdministrationUI/Basque.lproj/Localizable.strings
trans.fi = UI/AdministrationUI/Finnish.lproj/Localizable.strings
trans.fr = UI/AdministrationUI/French.lproj/Localizable.strings
trans.he = UI/AdministrationUI/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/AdministrationUI/Croatian.lproj/Localizable.strings
trans.hu = UI/AdministrationUI/Hungarian.lproj/Localizable.strings
trans.is = UI/AdministrationUI/Icelandic.lproj/Localizable.strings
@@ -260,6 +267,7 @@ trans.es_ES = SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings
trans.eu = SoObjects/Appointments/Basque.lproj/Localizable.strings
trans.fi = SoObjects/Appointments/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Appointments/French.lproj/Localizable.strings
trans.he = SoObjects/Appointments/Hebrew.lproj/Localizable.strings
trans.hr_HR = SoObjects/Appointments/Croatian.lproj/Localizable.strings
trans.hu = SoObjects/Appointments/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Appointments/Icelandic.lproj/Localizable.strings
@@ -295,6 +303,7 @@ trans.es_ES = SoObjects/Contacts/SpanishSpain.lproj/Localizable.strings
trans.eu = SoObjects/Contacts/Basque.lproj/Localizable.strings
trans.fi = SoObjects/Contacts/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Contacts/French.lproj/Localizable.strings
trans.he = SoObjects/Contacts/Hebrew.lproj/Localizable.strings
trans.hr_HR = SoObjects/Contacts/Croatian.lproj/Localizable.strings
trans.hu = SoObjects/Contacts/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Contacts/Icelandic.lproj/Localizable.strings
@@ -330,6 +339,7 @@ trans.es_ES = SoObjects/Mailer/SpanishSpain.lproj/Localizable.strings
trans.eu = SoObjects/Mailer/Basque.lproj/Localizable.strings
trans.fi = SoObjects/Mailer/Finnish.lproj/Localizable.strings
trans.fr = SoObjects/Mailer/French.lproj/Localizable.strings
trans.he = SoObjects/Mailer/Hebrew.lproj/Localizable.strings
trans.hr_HR = SoObjects/Mailer/Croatian.lproj/Localizable.strings
trans.hu = SoObjects/Mailer/Hungarian.lproj/Localizable.strings
trans.is = SoObjects/Mailer/Icelandic.lproj/Localizable.strings
@@ -365,6 +375,7 @@ trans.es_ES = UI/MailPartViewers/SpanishSpain.lproj/Localizable.strings
trans.eu = UI/MailPartViewers/Basque.lproj/Localizable.strings
trans.fi = UI/MailPartViewers/Finnish.lproj/Localizable.strings
trans.fr = UI/MailPartViewers/French.lproj/Localizable.strings
trans.he = UI/MailPartViewers/Hebrew.lproj/Localizable.strings
trans.hr_HR = UI/MailPartViewers/Croatian.lproj/Localizable.strings
trans.hu = UI/MailPartViewers/Hungarian.lproj/Localizable.strings
trans.is = UI/MailPartViewers/Icelandic.lproj/Localizable.strings
+95 -4
View File
@@ -83,7 +83,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSArray *emails, *addresses, *categories, *elements;
CardElement *n, *homeAdr, *workAdr;
NSMutableArray *other_addresses;
CardElement *n, *homeAdr, *workAdr, *otherAdr;
NSMutableString *s, *a;
NSString *url;
id o;
@@ -186,7 +187,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [homeAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<HomeStreet xmlns=\"Contacts:\">%@</HomeStreet>", [a activeSyncRepresentationInContext: context]];
[s appendFormat: @"<HomeStreet xmlns=\"Contacts:\">%@</HomeStreet>", a];
if ((o = [homeAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<HomeCity xmlns=\"Contacts:\">%@</HomeCity>", [o activeSyncRepresentationInContext: context]];
@@ -217,7 +218,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [workAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<BusinessStreet xmlns=\"Contacts:\">%@</BusinessStreet>", [a activeSyncRepresentationInContext: context]];
[s appendFormat: @"<BusinessStreet xmlns=\"Contacts:\">%@</BusinessStreet>", a];
if ((o = [workAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<BusinessCity xmlns=\"Contacts:\">%@</BusinessCity>", [o activeSyncRepresentationInContext: context]];
@@ -232,6 +233,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendFormat: @"<BusinessCountry xmlns=\"Contacts:\">%@</BusinessCountry>", [o activeSyncRepresentationInContext: context]];
}
// Other Address
other_addresses = [[self childrenWithTag: @"adr"] mutableCopy];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"work"]];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"home"]];
if ([other_addresses count])
{
otherAdr = [other_addresses objectAtIndex: 0];
a = [NSMutableString string];
if ((o = [otherAdr flattenedValueAtIndex: 2 forKey: @""]))
[a appendString: [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
[s appendFormat: @"<OtherStreet xmlns=\"Contacts:\">%@</OtherStreet>", a];
if ((o = [otherAdr flattenedValueAtIndex: 3 forKey: @""]))
[s appendFormat: @"<OtherCity xmlns=\"Contacts:\">%@</OtherCity>", [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 4 forKey: @""]))
[s appendFormat: @"<OtherState xmlns=\"Contacts:\">%@</OtherState>", [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 5 forKey: @""]))
[s appendFormat: @"<OtherPostalCode xmlns=\"Contacts:\">%@</OtherPostalCode>", [o activeSyncRepresentationInContext: context]];
if ((o = [otherAdr flattenedValueAtIndex: 6 forKey: @""]))
[s appendFormat: @"<OtherCountry xmlns=\"Contacts:\">%@</OtherCountry>", [o activeSyncRepresentationInContext: context]];
}
// Other, less important fields
if ((o = [self birthday]))
{
@@ -267,7 +301,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inContext: (WOContext *) context
{
CardElement *element;
NSMutableArray *addressLines;
NSMutableArray *addressLines, *other_addresses;
id o;
// Contact's note
@@ -398,6 +432,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
atIndex: 6 forKey: @""];
}
// OtherCountry
//
other_addresses = [[self childrenWithTag: @"adr"] mutableCopy];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"work"]];
[other_addresses removeObjectsInArray: [self childrenWithTag: @"adr" andAttribute: @"type" havingValue: @"home"]];
if ([other_addresses count])
element = [other_addresses objectAtIndex: 0];
else
{
element = [CardElement elementWithTag: @"adr"];
[self addChild: element];
}
if ((o = [theValues objectForKey: @"OtherStreet"]) || ![self _isGhosted: @"OtherStreet" inContext: context])
{
addressLines = [NSMutableArray arrayWithArray: [o componentsSeparatedByString: @"\n"]];
[element setSingleValue: @""
atIndex: 1 forKey: @""];
[element setSingleValue: [addressLines count] ? [addressLines objectAtIndex: 0] : @""
atIndex: 2 forKey: @""];
// Extended address line. If there are more then 2 address lines we add them to the extended address line.
if ([addressLines count] > 1)
{
[addressLines removeObjectAtIndex: 0];
[element setSingleValue: [addressLines componentsJoinedByString: @" "]
atIndex: 1 forKey: @""];
}
}
if ((o = [theValues objectForKey: @"OtherCity"]) || ![self _isGhosted: @"OtherCity" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherCity"]
atIndex: 3 forKey: @""];
}
if ((o = [theValues objectForKey: @"OtherState"]) || ![self _isGhosted: @"OtherState" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherState"]
atIndex: 4 forKey: @""];
}
if ((o = [theValues objectForKey: @"OtherPostalCode"]) || ![self _isGhosted: @"OtherPostalCode" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherPostalCode"]
atIndex: 5 forKey: @""];
}
if ((o = [theValues objectForKey: @"OtherCountry"]) || ![self _isGhosted: @"OtherCountry" inContext: context])
{
[element setSingleValue: [theValues objectForKey: @"OtherCountry"]
atIndex: 6 forKey: @""];
}
// Company's name
if ((o = [theValues objectForKey: @"CompanyName"]))
[self setOrg: o units: nil];
+9
View File
@@ -148,6 +148,10 @@ static NSArray *easCommandParameters = nil;
const char* qs_bytes;
queryString = [[components objectAtIndex: 0] dataByDecodingBase64];
if (![queryString length])
return nil;
qs_bytes = (const char*)[queryString bytes];
return [NSString stringWithFormat:@"%.1f", (float)((uint8_t)qs_bytes[0]/10)];
@@ -196,6 +200,11 @@ static NSArray *easCommandParameters = nil;
// Command code, 1 byte, ie.: cmd=
cmd_code = qs_bytes[1];
// Check whether the command code is within the known range.
if (cmd_code < 0 || cmd_code > 22)
return nil;
[components addObject: [NSString stringWithFormat: @"cmd=%@", [easCommandCodes objectAtIndex: cmd_code]]];
// Device ID length and Device ID (variable)
+65 -6
View File
@@ -53,9 +53,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <SOGo/SOGoCacheGCSObject.h>
#import <SOGo/SOGoPermissions.h>
#import <NGCards/iCalCalendar.h>
#import <Appointments/iCalEntityObject+SOGo.h>
#import <Appointments/SOGoAppointmentObject.h>
#import <Appointments/SOGoTaskObject.h>
#import <Appointments/SOGoAppointmentFolder.h>
#import <Contacts/SOGoContactGCSEntry.h>
@@ -227,7 +230,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
return nameInCache;
}
- (void) _removeAllAlarmsFromCalendar: (iCalCalendar *) theCalendar
{
NSArray *allComponents;
iCalEntityObject *currentComponent;
NSUInteger count, max;
if (debugOn)
[self logWithFormat: @"EAS - Remove all alarms"];
allComponents = [theCalendar allObjects];
max = [allComponents count];
for (count = 0; count < max; count++)
{
currentComponent = [allComponents objectAtIndex: count];
if ([currentComponent isKindOfClass: [iCalEvent class]] ||
[currentComponent isKindOfClass: [iCalToDo class]])
[currentComponent removeAllAlarms];
}
}
//
// <?xml version="1.0"?>
@@ -269,6 +291,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processSyncAddCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
objectsToTouch: (NSMutableArray *) objectsToTouch
inBuffer: (NSMutableString *) theBuffer
{
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *uidCache, *allValues;
@@ -280,6 +303,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
int i;
additions = (id)[theDocumentElement getElementsByTagName: @"Add"];
if ([additions count])
{
for (i = 0; i < [additions count]; i++)
@@ -367,9 +391,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
[o takeActiveSyncValues: allValues inContext: context];
[sogoObject setIsNew: is_new];
[sogoObject saveComponent: o];
if (theFolderType == ActiveSyncEventFolder)
[sogoObject saveComponent: o force: YES];
else
[sogoObject saveComponent: o];
}
if ([sogoObject isKindOfClass: [SOGoAppointmentObject class]] && [sogoObject resourceHasAutoAccepted])
[objectsToTouch addObject: sogoObject];
// Update syncCache
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
@@ -421,7 +453,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", easId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Add>"];
}
}
}
@@ -465,7 +496,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processSyncChangeCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
objectsToTouch: (NSMutableArray *) objectsToTouch
inBuffer: (NSMutableString *) theBuffer
{
NSDictionary *allChanges;
NSString *serverId, *easId, *origServerId, *mergedFolder;
@@ -505,6 +537,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncChangeCommand: theDocumentElement
inCollection: [self collectionFromId: mergedFolder type: theFolderType]
withType: theFolderType
objectsToTouch: objectsToTouch
inBuffer: theBuffer];
continue;
@@ -588,7 +621,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ([roles containsObject: SOGoCalendarRole_ComponentModifier] || [[sogoObject ownerInContext: context] isEqualToString: [[context activeUser] login]])
{
[o takeActiveSyncValues: allChanges inContext: context];
[sogoObject saveComponent: o];
if (theFolderType == ActiveSyncEventFolder)
{
[sogoObject saveComponent: o force: YES];
if ([sogoObject resourceHasAutoAccepted])
[objectsToTouch addObject: sogoObject];
}
else
[sogoObject saveComponent: o];
if ([syncCache objectForKey: serverId])
[syncCache setObject: [NSString stringWithFormat: @"%f", [[sogoObject lastModified] timeIntervalSince1970]] forKey: serverId];
@@ -1202,6 +1243,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
d = [NSCalendarDate distantFuture];
[dateCache setObject: d forKey: uid];
if (!([theCollection showCalendarAlarms]))
[self _removeAllAlarmsFromCalendar: [componentObject parent]];
}
if (updated)
@@ -1562,7 +1606,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: [mailObject activeSyncRepresentationInContext: context]];
[s appendString: @"</ApplicationData>"];
[s appendString: @"</Add>"];
[syncCache setObject: [aCacheObject sequence] forKey: [aCacheObject uid]];
[dateCache setObject: [NSCalendarDate date] forKey: [aCacheObject uid]];
@@ -1637,6 +1681,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
objectsToTouch: (NSMutableArray *) objectsToTouch
processed: (BOOL *) processed
{
id <DOMElement> aCommand, element;
@@ -1665,6 +1710,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncAddCommand: element
inCollection: theCollection
withType: theFolderType
objectsToTouch: objectsToTouch
inBuffer: theBuffer];
*processed = YES;
}
@@ -1674,6 +1720,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncChangeCommand: element
inCollection: theCollection
withType: theFolderType
objectsToTouch: objectsToTouch
inBuffer: theBuffer];
*processed = YES;
}
@@ -1711,7 +1758,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *mimeSupport, *mimeTruncation, *filterType, *lastServerKey, *syncKeyInCache, *folderKey;
NSMutableDictionary *folderMetadata, *folderOptions;
NSMutableArray *supportedElements, *supportedElementNames;
NSMutableArray *supportedElements, *supportedElementNames, *objectsToTouch;
NSMutableString *changeBuffer, *commandsBuffer;
id collection, value;
@@ -1941,6 +1988,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// We process the commands from the request
//
objectsToTouch = [NSMutableArray array];
if (!first_sync)
{
NSMutableString *s;
@@ -1953,6 +2002,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inCollection: collection
withType: folderType
inBuffer: s
objectsToTouch: objectsToTouch
processed: &processed];
// Windows phones don't like empty Responses tags - such as: <Responses></Responses>.
@@ -2271,6 +2321,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendString: changeBuffer];
[theBuffer appendString: @"</Collection>"];
// We touch objects (likely only SOGoAppointmentObjects for now) that might have been changed
// by the server and that we want the EAS client to re-pull. For example, that's the case for
// auto-accepted events by resources
for (i = 0; i < [objectsToTouch count]; i++)
{
sleep(1);
[[objectsToTouch objectAtIndex: i] touch];
}
}
//
+175 -64
View File
@@ -43,6 +43,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGObjWeb/WOCoreApplication.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalPerson.h>
#import <NGExtensions/NGBase64Coding.h>
@@ -59,8 +61,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGMime/NGMimeBodyPart.h>
#import <NGMime/NGMimeFileData.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMime/NGMimeType.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMime/NGConcreteMimeType.h>
#import <NGMail/NGMimeMessageParser.h>
#import <NGMail/NGMimeMessageGenerator.h>
@@ -947,6 +950,7 @@ void handle_eas_terminate(int signum)
command_count++;
}
[o destroy];
continue;
}
// Remove the folder from device if it is a contact folder and we have no SOGoRole_ObjectViewer.
@@ -1097,6 +1101,7 @@ void handle_eas_terminate(int signum)
![currentFolder synchronize])
{
[folders removeObjectAtIndex: count];
continue;
}
// Remove the folder from the device if it is a contact folder and we have no SOGoRole_ObjectViewer access right.
@@ -1815,7 +1820,7 @@ void handle_eas_terminate(int signum)
{
appointmentObject = [[SOGoAppointmentObject alloc] initWithName: [NSString stringWithFormat: @"%@.ics", [event uid]]
inContainer: collection];
[appointmentObject saveComponent: event];
[appointmentObject saveComponent: event force: YES];
}
if (uidCache && [calendarId length] > 64)
@@ -2651,6 +2656,7 @@ void handle_eas_terminate(int signum)
NSData *d;
unsigned int startdate, enddate, increments;
NGCalendarDateRange *r1, *r2;
char c;
startDate = [[[(id)[theDocumentElement getElementsByTagName: @"StartTime"] lastObject] textValue] calendarDate];
@@ -2697,17 +2703,13 @@ void handle_eas_terminate(int signum)
folder = [user personalCalendarFolderInContext: context];
freebusy = [folder fetchFreeBusyInfosFrom: startDate to: endDate];
NGCalendarDateRange *r1, *r2;
for (j = 1; j <= increments; j++)
for (j = 0; j < increments; j++)
{
c = '0';
r1 = [NGCalendarDateRange calendarDateRangeWithStartDate: [NSDate dateWithTimeIntervalSince1970: (startdate+j*30*60)]
endDate: [NSDate dateWithTimeIntervalSince1970: (startdate+j*30*60 + 30)]];
for (k = 0; k < [freebusy count]; k++)
{
@@ -2725,11 +2727,8 @@ void handle_eas_terminate(int signum)
[s appendFormat: @"%c", c];
}
[s appendString: @"</MergedFreeBusy>"];
[s appendString: @"</Availability>"];
[s appendString: @"</Recipient>"];
[s appendString: @"</Response>"];
}
@@ -2760,7 +2759,7 @@ void handle_eas_terminate(int signum)
inResponse: (WOResponse *) theResponse
{
SOGoContactSourceFolder *currentFolder;
NSArray *allKeys, *allContacts, *mails;
NSArray *allKeys, *allContacts, *mails, *a;
NSDictionary *systemSources, *contact;
SOGoContactFolders *contactFolders;
NSString *current_mail, *query;
@@ -2770,7 +2769,10 @@ void handle_eas_terminate(int signum)
NSData *d;
id o;
int i, j, total;
int i, j, t, v, total, minResult, maxResult, maxSize, maxPictures;
BOOL withPhoto;
withPhoto = NO;
query = [[(id)[theDocumentElement getElementsByTagName: @"Query"] lastObject] textValue];
@@ -2779,6 +2781,33 @@ void handle_eas_terminate(int signum)
systemSources = [contactFolders systemSources];
allKeys = [systemSources allKeys];
// We check for the maximum number of results to return.
a = [[[(id)[theDocumentElement getElementsByTagName: @"Range"] lastObject] textValue] componentsSeparatedByString: @"-"];
minResult = [[a objectAtIndex: 0] intValue];
maxResult = [[a objectAtIndex: 1] intValue];
if (maxResult == 0)
maxResult = 99;
if ((o = [(id)[[(id)[theDocumentElement getElementsByTagName: @"Options"] lastObject] getElementsByTagName: @"Picture"] lastObject]))
{
withPhoto = YES;
// We check for a MaxSize, default to 102400.
maxSize = [[[(id)[o getElementsByTagName: @"MaxSize"] lastObject] textValue] intValue];
// We check if we must overwrite the maxSize with a system preference. This can be useful
// if we don't want to have pictures in the response.
if ((v = [[SOGoSystemDefaults sharedSystemDefaults] maximumPictureSize]))
maxSize = v;
// We check for a MaxPictures, default to 99.
maxPictures = [[[(id)[o getElementsByTagName: @"MaxPictures"] lastObject] textValue] intValue];
if (maxPictures == 0)
maxPictures = 99;
}
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
@@ -2800,7 +2829,7 @@ void handle_eas_terminate(int signum)
ordering: NSOrderedAscending
inDomain: [[context activeUser] domain]];
for (j = 0; j < [allContacts count]; j++)
for (j = minResult; (j < [allContacts count] && j < maxResult) ; j++)
{
contact = [allContacts objectAtIndex: j];
@@ -2818,42 +2847,60 @@ void handle_eas_terminate(int signum)
else
mails = [NSArray arrayWithObjects: o ? o : @"", nil];
for (total = 0; total < [mails count]; total++)
for (t = 0; t < [mails count]; t++)
{
current_mail = [mails objectAtIndex: total];
current_mail = [mails objectAtIndex: t];
[s appendString: @"<Result xmlns=\"Search:\">"];
[s appendString: @"<Properties>"];
if ((o = [contact objectForKey: @"displayname"]))
[s appendFormat: @"<DisplayName xmlns=\"Gal:\">%@</DisplayName>", o];
[s appendFormat: @"<DisplayName xmlns=\"Gal:\">%@</DisplayName>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"title"]))
[s appendFormat: @"<Title xmlns=\"Gal:\">%@</Title>", o];
[s appendFormat: @"<Title xmlns=\"Gal:\">%@</Title>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"givenname"]))
[s appendFormat: @"<FirstName xmlns=\"Gal:\">%@</FirstName>", o];
[s appendFormat: @"<FirstName xmlns=\"Gal:\">%@</FirstName>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"sn"]))
[s appendFormat: @"<LastName xmlns=\"Gal:\">%@</LastName>", o];
[s appendFormat: @"<LastName xmlns=\"Gal:\">%@</LastName>", [o activeSyncRepresentationInContext: context]];
if ([current_mail length] > 0)
[s appendFormat: @"<EmailAddress xmlns=\"Gal:\">%@</EmailAddress>", current_mail];
[s appendFormat: @"<EmailAddress xmlns=\"Gal:\">%@</EmailAddress>", [current_mail activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"telephonenumber"]))
[s appendFormat: @"<Phone xmlns=\"Gal:\">%@</Phone>", o];
[s appendFormat: @"<Phone xmlns=\"Gal:\">%@</Phone>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"homephone"]))
[s appendFormat: @"<HomePhone xmlns=\"Gal:\">%@</HomePhone>", o];
[s appendFormat: @"<HomePhone xmlns=\"Gal:\">%@</HomePhone>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"mobile"]))
[s appendFormat: @"<MobilePhone xmlns=\"Gal:\">%@</MobilePhone>", o];
[s appendFormat: @"<MobilePhone xmlns=\"Gal:\">%@</MobilePhone>", [o activeSyncRepresentationInContext: context]];
if ((o = [contact objectForKey: @"o"]))
[s appendFormat: @"<Company xmlns=\"Gal:\">%@</Company>", o];
[s appendFormat: @"<Company xmlns=\"Gal:\">%@</Company>", [o activeSyncRepresentationInContext: context]];
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 14.1 && withPhoto)
{
o = [contact objectForKey: @"photo"];
if (o && [o length] <= maxSize && total < maxPictures)
{
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>1</Status><Data>"];
[s appendString: [o activeSyncRepresentationInContext: context]];
[s appendString: @"</Data></Picture>"];
}
else if (!o)
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>173</Status></Picture>"];
else if ([o length] > maxSize)
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>174</Status></Picture>"];
else if (total >= maxPictures)
[s appendString: @"<Picture xmlns=\"Gal:\"><Status>175</Status></Picture>"];
}
[s appendString: @"</Properties>"];
[s appendString: @"</Result>"];
total++;
}
}
}
@@ -3167,6 +3214,28 @@ void handle_eas_terminate(int signum)
return nil;
}
//
// See https://msdn.microsoft.com/en-us/library/ee218647(v=exchg.80).aspx
// for valid status codes.
//
- (NSData *) _sendMailErrorResponseWithStatus: (int) status
{
NSMutableString *s;
NSData *d;
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<SendMail xmlns=\"ComposeMail:\">"];
[s appendFormat: @"<Status>%d</Status>", status];
[s appendString: @"</SendMail>"];
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
return d;
}
//
//
//
@@ -3180,6 +3249,7 @@ void handle_eas_terminate(int signum)
NSData *new_from_header;
NSDictionary *identity;
NSString *fullName, *email;
NGMimeType *contentType;
NSArray *from;
const char *bytes;
@@ -3195,6 +3265,40 @@ void handle_eas_terminate(int signum)
message = [parser parsePartFromData: data];
RELEASE(parser);
// If an EAS client is trying to send an invitation email (request or response), we make sure to
// remove all attendees that have NO email addresses. Outlook 2016 (and likely other EAS clients)
// do that when sending IMIP only to "newly added or deleted attendees" - existing attendees have
// their email addresses stripped, while keeping the display name value.
contentType = [message contentType];
if ([contentType isKindOfClass: [NGConcreteTextMimeType class]] &&
[[[message contentType] subType] caseInsensitiveCompare: @"calendar"] == NSOrderedSame &&
([[(NGConcreteTextMimeType *)[message contentType] method] caseInsensitiveCompare: @"request"] == NSOrderedSame ||
[[(NGConcreteTextMimeType *)[message contentType] method] caseInsensitiveCompare: @"reply"] == NSOrderedSame))
{
NGMimeMessageGenerator *generator;
iCalCalendar *calendar;
iCalPerson *attendee;
NSArray *attendees;
iCalEvent *event;
calendar = [iCalCalendar parseSingleFromSource: [message body]];
event = [[calendar events] lastObject];
attendees = [event attendees];
for (i = [attendees count]-1; i >= 0; i--)
{
attendee = [attendees objectAtIndex: i];
if (![attendee rfc822Email] || [[attendee rfc822Email] caseInsensitiveCompare: @"nomail"] == NSOrderedSame)
[event removeFromAttendees: attendee];
}
// We regenerate the data to use
[message setBody: [[calendar versitString] dataUsingEncoding: NSUTF8StringEncoding]];
generator = [[[NGMimeMessageGenerator alloc] init] autorelease];
data = [NSMutableData dataWithData: [generator generateMimeFromPart: message]];
}
from = [message headersForKey: @"from"];
if (![from count] || ![self _isEMailValid: [[from objectAtIndex: 0] pureEMailAddress]] ||
@@ -3296,20 +3400,7 @@ void handle_eas_terminate(int signum)
{
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 14.0)
{
NSMutableString *s;
NSData *d;
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<SendMail xmlns=\"ComposeMail:\">"];
[s appendString: @"<Status>120</Status>"];
[s appendString: @"</SendMail>"];
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
[theResponse setContent: d];
[theResponse setContent: [self _sendMailErrorResponseWithStatus: 120]];
}
else
{
@@ -3498,10 +3589,14 @@ void handle_eas_terminate(int signum)
{
NSString *folderId, *itemId, *realCollectionId;
SOGoMicrosoftActiveSyncFolderType folderType;
SOGoMailAccounts *accountsFolder;
SOGoMailFolder *currentFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;
SOGoUserDefaults *ud;
BOOL htmlComposition, isHTML;
id value;
id value, currentCollection;
isHTML = NO;
ud = [[context activeUser] userDefaults];
@@ -3527,23 +3622,31 @@ void handle_eas_terminate(int signum)
value = [theDocumentElement getElementsByTagName: @"ReplaceMime"];
// We fetch the mail object from the server
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%@", realCollectionId]
inContext: context
acquire: NO];
mailObject = [currentCollection lookupName: itemId inContext: context acquire: NO];
// ReplaceMime IS specified so we must NOT use the server copy
// but rather take the data as-is from the client.
if ([value count])
{
[self processSendMail: theDocumentElement
inResponse: theResponse];
[self processSendMail: theDocumentElement inResponse: theResponse];
if (!isSmartForward)
[mailObject addFlags: @"Answered"];
else
[mailObject addFlags: @"$Forwarded"];
return;
}
if (folderType == ActiveSyncMailFolder)
{
SOGoMailAccounts *accountsFolder;
SOGoMailFolder *currentFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;
id currentCollection;
NGMimeMessage *messageFromSmartForward, *messageToSend;
NGMimeMessageParser *parser;
NSData *data;
@@ -3562,16 +3665,6 @@ void handle_eas_terminate(int signum)
int a;
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%@", realCollectionId]
inContext: context
acquire: NO];
mailObject = [currentCollection lookupName: itemId inContext: context acquire: NO];
parser = [[NGMimeMessageParser alloc] init];
data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding];
messageFromSmartForward = [parser parsePartFromData: data];
@@ -3937,6 +4030,14 @@ void handle_eas_terminate(int signum)
// Get the device ID, device type and "stash" them
deviceId = [[theRequest uri] deviceId];
if ([deviceId isEqualToString: @"Unknown"])
{
[(WOResponse *)theResponse setStatus: 500];
[self logWithFormat: @"EAS - No device id provided, ignoring request."];
return nil;
}
[context setObject: deviceId forKey: @"DeviceId"];
[context setObject: [[theRequest uri] deviceType] forKey: @"DeviceType"];
[context setObject: [[theRequest uri] attachmentName] forKey: @"AttachmentName"];
@@ -3993,23 +4094,32 @@ void handle_eas_terminate(int signum)
}
xml = [NSString stringWithFormat: @"<?xml version=\"1.0\"?><!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\"><%@ xmlns=\"ComposeMail:\"><SaveInSentItems/><MIME>%@</MIME></%@>", cmdName, [s stringByEncodingBase64], cmdName];
d = [xml dataUsingEncoding: NSASCIIStringEncoding];
}
else
{
d = [[theRequest content] wbxml2xml];
// Handle empty Ping request, no need to try decoding the WBXML blob here
if ([[theRequest content] length])
d = [[theRequest content] wbxml2xml];
else
d = nil;
}
documentElement = nil;
if (!d)
{
// If we got no data in the SendMail request, that means SOPE rejected it because of the WOMaxUploadSize.
// We generate here the proper failed response for SendMail
if ([cmdName caseInsensitiveCompare: @"SendMail"] == NSOrderedSame)
{
[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];
[theResponse setContent: [self _sendMailErrorResponseWithStatus: 122]];
goto return_response;
}
// 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 && [cmdName caseInsensitiveCompare: @"Sync"] != NSOrderedSame)
else if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"Sync"] != NSOrderedSame)
{
RELEASE(context);
RELEASE(pool);
@@ -4047,6 +4157,7 @@ void handle_eas_terminate(int signum)
[self performSelector: aSelector withObject: documentElement withObject: theResponse];
return_response:
[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.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
+46 -36
View File
@@ -163,7 +163,7 @@ struct GlobalObjectId {
const char *bytes;
uid = [event uid];
uidAsASCII = [uid decodeFromHexidecimal];
uidAsASCII = [uid dataUsingEncoding: NSASCIIStringEncoding];
newGlobalId = (struct GlobalObjectId*)calloc(sizeof(uint8_t), sizeof(struct GlobalObjectId) + 0x0c + [uidAsASCII length]);
prefix = @"040000008200e00074c5b7101a82e008";
@@ -726,12 +726,53 @@ struct GlobalObjectId {
//
//
//
- (iCalCalendar *) calendarFromIMIPMessage
- (iCalCalendar *) _calendarFromParts: (NSArray *) parts
parent: (id) parent
{
NSDictionary *part;
id bodyPart;
int i;
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
bodyPart = [parent lookupImap4BodyPartKey: [NSString stringWithFormat: @"%d", i+1]
inContext: self->context];
if ([[part objectForKey: @"type"] isEqualToString: @"text"] &&
[[part objectForKey: @"subtype"] isEqualToString: @"calendar"])
{
if (bodyPart)
{
iCalCalendar *calendar;
NSData *calendarData;
calendarData = [bodyPart fetchBLOBWithPeek: YES];
calendar = nil;
NS_DURING
calendar = [iCalCalendar parseSingleFromSource: calendarData];
NS_HANDLER
calendar = nil;
NS_ENDHANDLER
return calendar;
}
}
else if ([[part objectForKey: @"type"] isEqualToString: @"multipart"])
return [self _calendarFromParts: [part objectForKey: @"parts"] parent: bodyPart];
}
return nil;
}
//
//
//
- (iCalCalendar *) calendarFromIMIPMessage
{
NSString *type, *subtype;
NSArray *parts;
int i;
type = [[[self bodyStructure] valueForKey: @"type"] lowercaseString];
subtype = [[[self bodyStructure] valueForKey: @"subtype"] lowercaseString];
@@ -764,38 +805,7 @@ struct GlobalObjectId {
parts = [[self bodyStructure] objectForKey: @"parts"];
if ([parts count] > 1)
{
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
if ([[part objectForKey: @"type"] isEqualToString: @"text"] &&
[[part objectForKey: @"subtype"] isEqualToString: @"calendar"])
{
id bodyPart;
bodyPart = [self lookupImap4BodyPartKey: [NSString stringWithFormat: @"%d", i+1]
inContext: self->context];
if (bodyPart)
{
iCalCalendar *calendar;
NSData *calendarData;
calendarData = [bodyPart fetchBLOBWithPeek: YES];
calendar = nil;
NS_DURING
calendar = [iCalCalendar parseSingleFromSource: calendarData];
NS_HANDLER
calendar = nil;
NS_ENDHANDLER
return calendar;
}
}
}
}
return [self _calendarFromParts: parts parent: self];
return nil;
}
@@ -934,7 +944,7 @@ struct GlobalObjectId {
else if ([method isEqualToString: @"COUNTER"])
className = @"IPM.Schedule.Meeting.Resp.Tent";
else if ([method isEqualToString: @"CANCEL"])
className = @"IPM.Schedule.Meeting.Cancelled";
className = @"IPM.Schedule.Meeting.Canceled";
else
className = @"IPM.Appointment";
+48 -28
View File
@@ -36,6 +36,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGCards/iCalAlarm.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalTrigger.h>
#import <NGCards/NSCalendarDate+NGCards.h>
#include "NSDate+ActiveSync.h"
@implementation iCalAlarm (ActiveSync)
@@ -53,9 +56,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nextAlarmDate = [self nextAlarmDate];
delta = (int)(([[(iCalEvent *)parent startDate] timeIntervalSince1970] - [nextAlarmDate timeIntervalSince1970])/60);
// don't send negative reminder - not supported
if (delta > 0)
[s appendFormat: @"<Reminder xmlns=\"Calendar:\">%d</Reminder>", (int)delta];
if ([parent isKindOfClass: [iCalEvent class]])
{
// don't send negative reminder - not supported
if (delta > 0)
[s appendFormat: @"<Reminder xmlns=\"Calendar:\">%d</Reminder>", (int)delta];
}
else
{
[s appendFormat: @"<ReminderTime xmlns=\"Task:\">%@</ReminderTime>", [nextAlarmDate activeSyncRepresentationInContext: context]];
}
}
return s;
@@ -67,37 +77,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
iCalTrigger *trigger;
id o;
o = [theValues objectForKey: @"Reminder"];
// Outlook: if reminder is set to 0 minutes before start save it as 1 minute since -> 0 minutes in not accepted by SOGo
if ([o isEqualToString: @"0"])
o = @"1";
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DURATION"];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
// SOGo web ui only supports 1w but not 2w (custom reminder only supports min/hours/days)
// 1week = -P1W
// 2weeks > -PxD
// xdays > -PxD
// xhours -> -PTxH
// xmin -> -PTxM
if ([o intValue] == 10080)
[trigger setSingleValue: [NSString stringWithFormat: @"-P1W" ] forKey: @""];
else
if ((o = [theValues objectForKey: @"Reminder"]))
{
if (([o intValue] % 1440) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-P%dD", ([o intValue] / 1440)] forKey: @""];
// Outlook: if reminder is set to 0 minutes before starttime, save it as 1 minute since -> 0 minutes in not accepted by SOGo
if ([o isEqualToString: @"0"])
o = @"1";
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DURATION"];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
// SOGo web ui only supports 1w but not 2w (custom reminder only supports min/hours/days)
// 1week = -P1W
// 2weeks > -PxD
// xdays > -PxD
// xhours -> -PTxH
// xmin -> -PTxM
if ([o intValue] == 10080)
[trigger setSingleValue: [NSString stringWithFormat: @"-P1W" ] forKey: @""];
else
{
if (([o intValue] % 60) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%dH", ([o intValue] / 60)] forKey: @""];
if (([o intValue] % 1440) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-P%dD", ([o intValue] / 1440)] forKey: @""];
else
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%@M", o] forKey: @""];
{
if (([o intValue] % 60) == 0)
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%dH", ([o intValue] / 60)] forKey: @""];
else
[trigger setSingleValue: [NSString stringWithFormat: @"-PT%@M", o] forKey: @""];
}
}
}
else if ((o = [theValues objectForKey: @"ReminderTime"]))
{
o = [o calendarDate];
trigger = [iCalTrigger elementWithTag: @"TRIGGER"];
[trigger setValueType: @"DATE-TIME"];
[trigger setSingleValue: [NSString stringWithFormat: @"%@Z", [o iCalFormattedDateTimeString]] forKey: @""];
[self setTrigger: trigger];
[self setAction: @"DISPLAY"];
}
}
@end
+15 -7
View File
@@ -231,9 +231,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
else
{
// If it's a normal event (ie, with no organizer/attendee) or we are the organizer to an event
// invitation, we set the busy status to 2 (Busy)
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", 2];
// If it's a normal event (i.e. with no organizer/attendee) or we are the organizer of an event
// invitation, we set the busy status depending on TRANSP.
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", (([self isOpaque]) ? 2 : 0)];
}
[s appendFormat: @"<MeetingStatus xmlns=\"Calendar:\">%d</MeetingStatus>", meetingStatus];
@@ -474,7 +474,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
if ((o = [theValues objectForKey: @"BusyStatus"]))
{
[o intValue];
if ([o boolValue])
[self setTransparency: @"OPAQUE"];
else
[self setTransparency: @"TRANSPARENT"];
}
//
@@ -602,7 +605,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
// Recurrence
if ((o = [theValues objectForKey: @"Recurrence"]))
if ((o = [theValues objectForKey: @"Recurrence"]) && [o isKindOfClass: [NSDictionary class]])
{
iCalRecurrenceRule *rule;
@@ -855,7 +858,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
person = [iCalPerson elementWithTag: @"attendee"];
[person setCn: [attendee objectForKey: @"Attendee_Name"]];
[person setEmail: [attendee objectForKey: @"Attendee_Email"]];
status = [[attendee objectForKey: @"Attendee_Status"] intValue];
switch (status)
@@ -872,7 +875,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
case 0:
case 5:
default:
[person setPartStat: @"NEEDS-ACTION"];
{
[person setPartStat: @"NEEDS-ACTION"];
[person setRsvp: @"TRUE"];
}
break;
}
@@ -884,6 +890,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self setAttendees: attendees];
}
}
[self setLastModified: [NSCalendarDate calendarDate]];
}
- (void) changeParticipationStatus: (NSDictionary *) theValues
@@ -134,6 +134,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"%@:\">%d</Recurrence_DayOfWeek>", t, (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"%@:\">%d</Recurrence_WeekOfMonth>", t, firstOccurrence];
[s appendFormat: @"<Recurrence_Interval xmlns=\"%@:\">%d</Recurrence_Interval>", t, [self repeatInterval]];
}
else if ([[self byMonthDay] count])
{
@@ -149,6 +150,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dm = [self byDayMask];
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"%@:\">%d</Recurrence_DayOfWeek>", t, (1 << [dm firstDay])];
[s appendFormat: @"<Recurrence_WeekOfMonth xmlns=\"%@:\">%d</Recurrence_WeekOfMonth>", t, 5];
[s appendFormat: @"<Recurrence_Interval xmlns=\"%@:\">%d</Recurrence_Interval>", t, [self repeatInterval]];
}
else
{
+25 -3
View File
@@ -43,9 +43,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalTimeZone.h>
#import <Appointments/iCalEntityObject+SOGo.h>
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
#include "iCalRecurrenceRule+ActiveSync.h"
#include "iCalAlarm+ActiveSync.h"
@implementation iCalToDo (ActiveSync)
@@ -95,8 +98,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
v = 1;
[s appendFormat: @"<Importance xmlns=\"Tasks:\">%d</Importance>", v];
// Reminder - FIXME
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 0];
// Reminder
if ([self hasAlarms])
{
iCalAlarm *alarm;
alarm = [self firstDisplayOrAudioAlarm];
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 1];
[s appendString: [alarm activeSyncRepresentationInContext: context]];
}
else
{
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 0];
}
// Sensitivity
if ([[self accessClass] isEqualToString: @"PRIVATE"])
@@ -145,7 +159,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: @"</Body>"];
}
}
return s;
}
@@ -249,6 +263,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [theValues objectForKey: @"ReminderTime"]))
{
iCalAlarm *alarm;
alarm = [[iCalAlarm alloc] init];
[alarm takeActiveSyncValues: theValues inContext: context];
[self removeAllAlarms];
[self addToAlarms: alarm];
RELEASE(alarm);
}
+15790 -11068
View File
File diff suppressed because it is too large. Load diff
+12 -6
View File
@@ -118,6 +118,11 @@ http://trochette.github.io/Angular-Design-Patterns-Best-Practices/
* Move business logic into models and share them.
* Keep it simple, separate server interaction and error handling from the model. That way model only handle data processing and code is easier to maintain.
Controllers
^^^^^^^^^^^
* Functions not exposed in the controller must be prefixed with an underscore.
SASS/CSS
~~~~~~~~
@@ -133,11 +138,6 @@ SASS/CSS
A `@mixin` is like a stamp: it creates a duplicated version of the property block (optionally) with arguments provided. An `@extend` appends the element you are extending to the property block. It is your "yes, and ___" statement.
* For documentation, we follow http://sassdoc.com/[SassDoc] annotations.
* We need the SASS files of Angular Material to build our CSS. The git repository of Angular Material is included as a submodule of SOGo:
git submodule init
git submodule update
* FlexBox compatibility http://caniuse.com/#feat=flexbox
Fonts
@@ -155,10 +155,16 @@ Building frontend
npm install -g grunt-cli
npm install -g bower
* Generate JavaScript files
* We need the SASS files of Angular Material to build our CSS. The git repository of Angular Material is included as a submodule of SOGo:
git submodule init
git submodule update
* Generate the JavaScript and CSS files
cd UI/WebServerResources
npm install
bower install
grunt build
Version Control
+21 -2
View File
@@ -238,6 +238,14 @@ sources, install the following package:
rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
----
SOGo relies on the GNUstep packages provided by Inverse and must not use the
packages from EPEL. Adjust the repository definition to exclude those packages:
----
sed -i '/enabled=1/a \
exclude=gnustep*' /etc/yum.repos.d/epel.repo
----
For more information on EPEL, visit http://fedoraproject.org/wiki/EPEL/.
Software Installation
@@ -391,9 +399,14 @@ internet connection could be killed prematurely.
|Parameter used to set the maximum allowed size for content being
sent to SOGo using a PUT or a POST call. This can also limit the file
attachment size being uploaded to SOGo when composing a mail. The
value is in kilobyte. By default, the value is 0, or disabled so no
value is in kilobytes. By default, the value is 0, or disabled so no
limit will be set.
|S |SOGoMaximumMessageSizeLimit
|Parameter used to set the maximum allowed email message size when
composing a mail. The value is in kilobytes. By default, the value is 0,
or disabled so no limit will be set.
|S |SxVMemLimit
|Parameter used to set the maximum amount of memory (in
megabytes) that a child can use. Reaching that value will force children
@@ -501,7 +514,7 @@ 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
|Mandatory parameter used to set a default time zone for users. The default
timezone is set to UTC. The Olson database is a standard database that
takes all the time zones around the world into account and represents
them along with their history. On GNU/Linux systems, time zone
@@ -2721,6 +2734,12 @@ have unexpected behaviour with various ActiveSync clients.
EAS command.
Defaults to `NO`, which means no logging is performed.
|S |SOGoMaximumPictureSize
|Parameter used to overwrite the maximum number of bytes returned in the picture
for EAS Search operations in the GAL.
If not set, it defaults to `102400` bytes, or 100 KB.
|=======================================================================
Please be aware of the following limitations:
+3 -3
View File
@@ -1,7 +1,7 @@
<!-- TODO have the build system take care of this -->
<releaseinfo>Version 3.2.3 - November 2016</releaseinfo>
<subtitle>for version 3.2.3</subtitle>
<date>2016-11-25</date>
<releaseinfo>Version 3.2.9 - May 2017</releaseinfo>
<subtitle>for version 3.2.9</subtitle>
<date>2017-05-09</date>
<legalnotice>
<para>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".</para>
@@ -6,13 +6,13 @@
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2008-2016 Inverse inc.
Copyright (C) 2008-2017 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: 3.2.3
:release_version: 3.2.9
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
+16 -5
View File
@@ -27,6 +27,7 @@
#import <GDLContentStore/GCSAlarmsFolder.h>
#import <GDLContentStore/GCSSessionsFolder.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoClassSecurityInfo.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest+So.h>
@@ -114,7 +115,7 @@ static BOOL debugLeaks;
vMemSizeLimit = [defaults vmemLimit];
if (vMemSizeLimit > 0)
[self logWithFormat: @"vmem size check enabled: shutting down app when "
@"vmem > %d MB", vMemSizeLimit];
@"vmem > %d MB. Currently at %d MB", vMemSizeLimit, [[NSProcessInfo processInfo] virtualMemorySize]/1048576];
/* SoClass security declarations */
sInfo = [self soClassSecurityInfo];
@@ -137,6 +138,8 @@ static BOOL debugLeaks;
/* load products */
[[SOGoProductLoader productLoader] loadAllProducts: YES];
if (vMemSizeLimit > 0)
[self logWithFormat: @"All products loaded - current memory usage at %d MB", [[NSProcessInfo processInfo] virtualMemorySize]/1048576];
}
- (id) init
@@ -418,8 +421,12 @@ static BOOL debugLeaks;
"GET" if no method was provided in the query path.
*/
if ([_key length] > 0 && ![_key isEqualToString:@"favicon.ico"])
obj = [self lookupUser: _key inContext: _ctx];
}
{
obj = [self lookupUser: _key inContext: _ctx];
if (!obj && ![_key isEqualToString: @"public"])
obj = [self lookupUser: @"anonymous" inContext: _ctx];
}
}
}
else
obj = nil;
@@ -445,8 +452,12 @@ static BOOL debugLeaks;
- (WOResponse *) handleException: (NSException *) _exc
inContext: (WOContext *) _ctx
{
printf("EXCEPTION: %s\n", [[_exc description] cString]);
abort();
WOResponse *resp;
NSLog(@"EXCEPTION: %s\n", [[_exc description] cString]);
resp = [WOResponse responseWithRequest: [_ctx request]];
[resp setStatus: 501];
return resp;
}
/* runtime maintenance */
+183
View File
@@ -1,3 +1,186 @@
3.2.9 (2017-05-09)
------------------
New features
- [core] email alarms now have pretty formatting (#805)
Enhancements
- [core] improved event invitation for all day events (#4145)
- [web] improved interface refresh time with external IMAP accounts
- [eas] added photo support for GAL search operations
Bug fixes
- [web] fixed attachment path when inside multiple body parts
- [web] fixed email reminder with attendees (#4115)
- [web] prevented form to be marked dirty when changing password (#4138)
- [web] restored support for SOGoLDAPContactInfoAttribute
- [web] avoid duplicated email addresses in LDAP-based addressbook (#4129)
- [web] fixed mail delegation of pristine user accounts (#4160)
- [core] cherry-picked comma escaping fix from v2 (#3296)
- [core] fix sogo-tool restore potentially crashing on corrupted data (#4048)
- [core] handle properly mails using windows-1255 charset (#4124)
- [core] fixed email reminders sent multiple times (#4100)
- [core] fixed LDIF to vCard conversion for non-handled multi-value attributes (#4086)
- [core] properly honor the "include in freebusy" setting (#3354)
- [core] make sure to use crypt scheme when encoding md5/sha256/sha512 (#4137)
- [eas] set reply/forwarded flags when ReplaceMime is set (#4133)
- [eas] remove alarms over EAS if we don't want them (#4059)
- [eas] correctly set RSVP on event invitations
- [eas] avoid sending IMIP request/update messages for all EAS clients (#4022)
3.2.8 (2017-03-24)
------------------
New features
- [core] new sogo-tool manage-acl command to manage calendar/address book ACLs
Enhancements
- [web] constrain event/task reminder to a positive number
- [web] display year in day and week views
- [web] split string on comma and semicolon when pasting multiple addresses (#4097)
- [web] restrict Draft/Sent/Trash/Junk mailboxes to the top level
- [web] animations are automatically disabled under IE11
- [web] updated Angular Material to version 1.1.3
Bug fixes
- [core] handle broken CalDAV clients sending bogus SENT-BY (#3992)
- [core] fixed handling of exdates and proper intersection for fbinfo (#4051)
- [core] remove attendees that have the same identity as the organizer (#3905)
- [web] fixed ACL editor in admin module for Safari (#4036)
- [web] fixed function call when removing contact category (#4039)
- [web] localized mailbox names everywhere (#4040, #4041)
- [web] hide fab button when printing (#4038)
- [web] SOGoCalendarWeekdays must now be defined before saving preferences
- [web] fixed CAS session timeout handling during XHR requests (#1456)
- [web] exposed default value of SOGoMailAutoSave (#4053)
- [web] exposed default value of SOGoMailAddOutgoingAddresses (#4064)
- [web] fixed handling of contact organizations (#4028)
- [web] fixed handling of attachments in mail editor (#4058, #4063)
- [web] fixed saving draft outside Mail module (#4071)
- [web] fixed SCAYT automatic language selection in HTML editor
- [web] fixed task sorting on multiple categories
- [web] fixed sanitisation of flags in Sieve filters (#4087)
- [web] fixed missing CC or BCC when specified before sending message (#3944)
- [web] enabled Save button after deleting attributes from a card (#4095)
- [web] don't show Copy To and Move To menu options when user has a single address book
- [web] fixed display of category colors in events and tasks lists
- [eas] fixed opacity in EAS freebusy (#4033)
3.2.7 (2017-02-14)
------------------
New features
- [core] new sogo-tool checkup command to make sure user's data is sane
Enhancements
- [web] added Hebrew (he) translation - thanks to Raz Aidlitz
Bug fixes
- [core] generalized the bcc handling code
- [web] saving the preferences was not possible when Mail module is disabled
- [web] ignore mouse events in scrollbars of Month view (#3990)
- [web] fixed public URL with special characters (#3993)
- [web] keep the fab button visible when the center list is hidden
- [web] localized mail, phone, url and address types (#4030)
- [eas] improved EAS parameters parsing (#4003)
- [eas] properly handle canceled appointments
3.2.6a (2017-01-26)
-------------------
Bug fixes
- [core] fixed "include in freebusy" (reverts #3354)
- [web] improved ACLs handling of inactive users
3.2.6 (2017-01-23)
------------------
Enhancements
- [web] show locale codes beside language names in Preferences module
- [web] fixed visual glitches in Month view with Firefox
- [web] mail editor can now be expanded horizontally and automatically expands vertically
- [web] compose a new message inline or in a popup window
- [web] allow to select multiple files when uploading attachments (#3999)
- [web] use "date" extension of Sieve to enable/disable vacation auto-reply (#1530, #1949)
- [web] updated Angular to version 1.6.1
- [web] updated CKEditor to version 4.6.2
Bug fixes
- [core] remove all alarms before sending IMIP replies (#3925)
- [web] fixed rendering of forwared HTML message with inline images (#3981)
- [web] fixed pasting images in CKEditor using Chrome (#3986)
- [eas] make sure we trigger a download of service-side changed events
- [eas] now strip attendees with no email during MeetingResponse calls
3.2.5 (2017-01-10)
------------------
New features
- [web] download attachments of a message as a zip archive
Enhancements
- [core] improved IMIP handling from Exchange/Outlook clients
- [web] prevent using localhost on additional IMAP accounts
- [web] renamed buttons of alarm toast (#3945)
- [web] load photos of LDAP-based address books in contacts list (#3942)
- [web] added SOGoMaximumMessageSizeLimit to limit webmail message size
- [web] added photo support for LDIF import (#1084)
- [web] updated CKEditor to version 4.6.1
Bug fixes
- [core] honor blocking wrong login attempts within time interval (#2850)
- [core] better support for RFC 6638 (schedule-agent)
- [core] use source's domain when none defined and trying to match users (#3523)
- [core] handle delegation with no SENT-BY set (#3368)
- [core] properly honor the "include in freebusy" setting (#3354)
- [core] properly save next email alarm in the database (#3949)
- [core] fix events in floating time during CalDAV's PUT operation (#2865)
- [core] handle rounds in sha512-crypt password hashes
- [web] fixed confusion between owner and active user in ACLs management of Administration module
- [web] fixed JavaScript exception after renaming an address book
- [web] fixed Sieve folder encoding support (#3904)
- [web] fixed ordering of calendars when renaming or adding a calendar (#3931)
- [web] use the organizer's alarm by default when accepting IMIP messages (#3934)
- [web] switch on "Remember username" when cookie username is set
- [web] return login page for unknown users (#2135)
- [web] fixed saving monthly recurrence rule with "by day" condition (#3948)
- [web] fixed display of message content when enabling auto-reply (#3940)
- [web] don't allow to create lists in a remote address book (not yet supported)
- [web] fixed attached links in task viewer (#3963)
- [web] avoid duplicate mail entries in contact of LDAP-based address book (#3941)
- [web] append ics file extension when importing events (#2308)
- [web] handle URI in vCard photos (#2683)
- [web] handle semicolon in values during LDIF import (#1760)
- [web] fixed computation of week number (#3973, #3976)
- [web] fixed saving of inactive calendars (#3862, #3980)
- [web] fixed public URLs to Calendars (#3974)
- [web] fixed hotkeys in Mail module when a dialog is active (#3983)
- [eas] properly skip folders we don't want to synchronize (#3943)
- [eas] fixed 30 mins freebusy offset with S Planner
- [eas] now correctly handles reminders on tasks (#3964)
- [eas] always force save events creation over EAS (#3958)
- [eas] do not decode from hex the event's UID (#3965)
- [eas] add support for "other addresses" (#3966)
- [eas] provide correct response status when sending too big mails (#3956)
3.2.4 (2016-12-01)
------------------
New features
- [core] new sogo-tool cleanup user feature
Enhancements
- [core] added handling of BYSETPOS for BYDAY in recurrence rules
- [web] added sort by start date for tasks (#3840)
Bug fixes
- [web] fixed JavaScript exception when SOGo is launched from an external link (#3900)
- [web] restored fetching of freebusy information of MS Exchange contacts
- [web] fixed mail attribute when importing an LDIF file (#3878)
- [web] don't save empty custom auto-reply subject
- [web] fixed detection of session expiration
- [eas] properly escape all GAL responses (#3923)
3.2.3 (2016-11-25)
------------------
+1
View File
@@ -45,6 +45,7 @@ SOGo and its associated components are available in various languages. The follo
* [fi] Finnish - Kari Salmu
* [fr] French - [Inverse](http://www.inverse.ca/)
* [de] German - Alexander Greiner-Baer
* [he] Hebrew - Raz Aidlitz
* [hu] Hungarian - Sándor Kuti
* [is] Icelandic - Anna Jonna Armannsdottir
* [it] Italian - Alessio Fattorini
+2
View File
@@ -123,6 +123,7 @@
- (NSException *) deleteContentWithName: (NSString *) _name;
- (NSException *) deleteAllContent;
- (NSException *) purgeDeletedRecordsBefore: (unsigned int) days;
- (NSException *) touchContentWithName: (NSString *) _name;
- (NSException *) deleteFolder;
@@ -144,6 +145,7 @@
- (void) deleteAclWithSpecification: (EOFetchSpecification *) _fs;
- (unsigned int) recordsCountByExcludingDeleted: (BOOL) includeDeleted;
- (unsigned int) recordsCountDeletedBefore: (unsigned int) days;
- (NSCalendarDate *) lastModificationDate;
+163 -70
View File
@@ -68,7 +68,7 @@ static GCSStringFormatter *stringFormatter = nil;
+ (void) initialize
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
debugOn = [ud boolForKey:@"GCSFolderDebugEnabled"];
doLogStore = [ud boolForKey:@"GCSFolderStoreDebugEnabled"];
@@ -91,7 +91,7 @@ static GCSStringFormatter *stringFormatter = nil;
NSEnumerator *fields;
GCSFieldInfo *field;
NSString *fieldName;
if ((self = [super init])) {
folderManager = [_fm retain];
folderInfo = [_ftype retain];
@@ -114,7 +114,7 @@ static GCSStringFormatter *stringFormatter = nil;
if (![fieldName isEqualToString: @"c_name"])
[contentFieldNames addObject: fieldName];
}
folderId = [_folderId copy];
folderName = [[_path lastPathComponent] copy];
path = [_path copy];
@@ -124,7 +124,7 @@ static GCSStringFormatter *stringFormatter = nil;
folderTypeName = [_ftname copy];
ofFlags.requiresFolderSelect = 0;
ofFlags.sameTableForQuick =
ofFlags.sameTableForQuick =
[location isEqualTo:quickLocation] ? 1 : 0;
}
return self;
@@ -133,7 +133,7 @@ static GCSStringFormatter *stringFormatter = nil;
- (id) init
{
return [self initWithPath:nil primaryKey:nil
folderTypeName:nil folderType:nil
folderTypeName:nil folderType:nil
location:nil quickLocation:nil
aclLocation:nil
folderManager:nil];
@@ -271,13 +271,13 @@ static GCSStringFormatter *stringFormatter = nil;
NSDictionary *ui;
ui = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithUnsignedInt:_base],
[NSNumber numberWithUnsignedInt:_base],
@"GCSExpectedVersion",
[NSNumber numberWithUnsignedInt:_store],
@"GCSStoredVersion",
self, @"GCSFolder",
nil];
return [NSException exceptionWithName:@"GCSVersionMismatch"
reason:@"Transaction conflict during a GCS modification."
userInfo:ui];
@@ -369,7 +369,7 @@ static GCSStringFormatter *stringFormatter = nil;
requirement: (GCSTableRequirement) requirement
{
NSString *selectedFields;
if (requirement == bothTableRequired && [fields containsObject: @"c_name"])
selectedFields = [self _dottedFields: fields];
else
@@ -381,7 +381,7 @@ static GCSStringFormatter *stringFormatter = nil;
- (NSString *) _sqlForQualifier: (EOQualifier *) qualifier
{
NSMutableString *ms;
if (qualifier)
{
ms = [NSMutableString stringWithCapacity:32];
@@ -399,7 +399,7 @@ static GCSStringFormatter *stringFormatter = nil;
if ((count = [_so count]) == 0)
return nil;
sql = [NSMutableString stringWithCapacity:(count * 16)];
for (i = 0; i < count; i++) {
EOSortOrdering *so;
@@ -409,9 +409,9 @@ static GCSStringFormatter *stringFormatter = nil;
so = [_so objectAtIndex:i];
sel = [so selector];
column = [so key];
if (i > 0) [sql appendString:@", "];
if (sel_eq(sel, EOCompareAscending)) {
[sql appendString:column];
[sql appendString:@" ASC"];
@@ -558,21 +558,21 @@ static GCSStringFormatter *stringFormatter = nil;
error = [channel evaluateExpressionX:sql];
if (error)
{
[self errorWithFormat:@"%s: cannot execute quick-fetch SQL '%@': %@",
[self errorWithFormat:@"%s: cannot execute quick-fetch SQL '%@': %@",
__PRETTY_FUNCTION__, sql, error];
results = nil;
}
else
{
/* fetch results */
results = [NSMutableArray arrayWithCapacity: 64];
attrs = [channel describeResults: NO /* do not beautify names */];
while ((row = [channel fetchAttributes: attrs withZone: NULL]))
[results addObject: row];
/* release channels */
}
[self releaseChannel: channel];
// NSLog(@"/running query");
@@ -582,7 +582,7 @@ static GCSStringFormatter *stringFormatter = nil;
[self errorWithFormat:@" could not open storage channel!"];
results = nil;
}
return results;
}
@@ -764,7 +764,7 @@ andAttribute: (EOAttribute *)_attribute
EOAttribute *attribute;
id value;
unsigned i, count;
if (_row == nil || _table == nil)
return nil;
@@ -774,7 +774,7 @@ andAttribute: (EOAttribute *)_attribute
[sql appendString:@"UPDATE "];
[sql appendString:_table];
[sql appendString:@" SET "];
for (i = 0, count = [keys count]; i < count; i++) {
fieldName = [keys objectAtIndex:i];
@@ -823,7 +823,7 @@ andAttribute: (EOAttribute *)_attribute
{
EOAttribute *attribute;
EOEntity *entity;
entity = AUTORELEASE([[EOEntity alloc] init]);
[entity setName: _name];
[entity setExternalName: _name];
@@ -841,7 +841,7 @@ andAttribute: (EOAttribute *)_attribute
EOAttribute *attribute;
EOEntity *entity;
entity = [self _entityWithName: [self storeTableName]];
entity = [self _entityWithName: [self storeTableName]];
attribute = AUTORELEASE([[EOAttribute alloc] init]);
[attribute setName: @"c_version"];
@@ -873,7 +873,7 @@ andAttribute: (EOAttribute *)_attribute
- (EOSQLQualifier *) _qualifierUsingWhereColumn:(NSString *)_colname
isEqualTo:(id)_value
andColumn:(NSString *)_colname2
andColumn:(NSString *)_colname2
isEqualTo:(id)_value2
entity: (EOEntity *)_entity
withAdaptor: (EOAdaptor *)_adaptor
@@ -970,7 +970,7 @@ andAttribute: (EOAttribute *)_attribute
NSArray *rows;
NSException *error;
/* check preconditions */
/* check preconditions */
if (_name)
{
if (_content)
@@ -979,10 +979,10 @@ andAttribute: (EOAttribute *)_attribute
error = nil;
nowDate = [NSCalendarDate date];
now = [NSNumber numberWithUnsignedInt:[nowDate timeIntervalSince1970]];
if (doLogStore)
[self logWithFormat:@"should store content: '%@'\n%@", _name, _content];
rows = [self fetchFields: [NSArray arrayWithObjects:
@"c_version",
@"c_deleted",
@@ -1021,6 +1021,7 @@ andAttribute: (EOAttribute *)_attribute
NSInvocation *anInvocation;
SEL aSelector;
quickRow = nil;
aSelector = @selector(quickRecordFromContent:container:nameInContainer:);
aSignature = [[theComponent class] instanceMethodSignatureForSelector: aSelector];
anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
@@ -1035,16 +1036,16 @@ andAttribute: (EOAttribute *)_attribute
if (quickRow)
{
[quickRow setObject:_name forKey:@"c_name"];
if (doLogStore)
[self logWithFormat:@" store quick: %@", quickRow];
/* make content row */
contentRow = [NSMutableDictionary dictionaryWithCapacity:16];
if (ofFlags.sameTableForQuick)
[contentRow addEntriesFromDictionary:quickRow];
[contentRow setObject:_name forKey:@"c_name"];
[contentRow setObject:now forKey:@"c_lastmodified"];
if (isNewRecord)
@@ -1058,7 +1059,7 @@ andAttribute: (EOAttribute *)_attribute
[NSNumber numberWithInt:([storedVersion intValue] + 1)]
forKey:@"c_version"];
[contentRow setObject:_content forKey:@"c_content"];
/* open channels */
storeChannel = [self acquireStoreChannel];
if (storeChannel)
@@ -1080,14 +1081,14 @@ andAttribute: (EOAttribute *)_attribute
/* we check if we can call directly methods on our adaptor
channel delegate. If not, we generate SQL ourself since it'll
be a little bit faster and less complex than using GDL to do so */
hasInsertDelegate = [[storeChannel delegate]
hasInsertDelegate = [[storeChannel delegate]
respondsToSelector: @selector(adaptorChannel:willInsertRow:forEntity:)];
hasUpdateDelegate = [[storeChannel delegate]
respondsToSelector: @selector(adaptorChannel:willUpdateRow:describedByQualifier:)];
[[quickChannel adaptorContext] beginTransaction];
[[storeChannel adaptorContext] beginTransaction];
quickTableEntity = [self _quickTableEntity];
storeTableEntity = [self _storeTableEntity];
@@ -1097,10 +1098,10 @@ andAttribute: (EOAttribute *)_attribute
error = (hasInsertDelegate
? [quickChannel insertRowX: quickRow forEntity: quickTableEntity]
: [quickChannel
evaluateExpressionX: [self _generateInsertStatementForRow: quickRow
evaluateExpressionX: [self _generateInsertStatementForRow: quickRow
adaptor: [[quickChannel adaptorContext] adaptor]
tableName: [self quickTableName]]]);
if (!error)
error = (hasInsertDelegate
? [storeChannel insertRowX: contentRow forEntity: storeTableEntity]
@@ -1138,7 +1139,7 @@ andAttribute: (EOAttribute *)_attribute
andColumn: (*_baseVersion != 0 ? (id)@"c_version" : (id)nil)
isEqualTo: (*_baseVersion != 0 ? [NSNumber numberWithUnsignedInt: *_baseVersion] : (NSNumber *)nil)]]);
}
if (error)
{
[[storeChannel adaptorContext] rollbackTransaction];
@@ -1193,19 +1194,19 @@ andAttribute: (EOAttribute *)_attribute
NSException *error;
NSString *delsql;
NSCalendarDate *nowDate;
/* check preconditions */
if (_name == nil) {
return [NSException exceptionWithName:@"GCSDeleteException"
reason:@"no content filename was provided"
userInfo:nil];
}
if (doLogStore)
[self logWithFormat:@"should delete content: '%@'", _name];
/* open channels */
if ((storeChannel = [self acquireStoreChannel]) == nil) {
[self errorWithFormat:@"could not open storage channel!"];
return nil;
@@ -1242,7 +1243,7 @@ andAttribute: (EOAttribute *)_attribute
delsql = [delsql stringByAppendingFormat:@" AND c_folder_id = %@", folderId];
if ((error = [storeChannel evaluateExpressionX:delsql]) != nil) {
[self errorWithFormat:
@"%s: cannot delete content '%@': %@",
@"%s: cannot delete content '%@': %@",
__PRETTY_FUNCTION__, delsql, error];
}
else if (!ofFlags.sameTableForQuick) {
@@ -1256,19 +1257,19 @@ andAttribute: (EOAttribute *)_attribute
delsql = [delsql stringByAppendingFormat:@" AND c_folder_id = %@", folderId];
if ((error = [quickChannel evaluateExpressionX:delsql]) != nil) {
[self errorWithFormat:
@"%s: cannot delete quick row '%@': %@",
@"%s: cannot delete quick row '%@': %@",
__PRETTY_FUNCTION__, delsql, error];
/*
/*
Note: we now have a "broken" record, needs to be periodically GCed by
a script!
*/
}
}
/* release channels and return */
[adaptorCtx commitTransaction];
[self releaseChannel:storeChannel];
if (!ofFlags.sameTableForQuick) {
[[quickChannel adaptorContext] commitTransaction];
[self releaseChannel:quickChannel];
@@ -1307,7 +1308,7 @@ andAttribute: (EOAttribute *)_attribute
query = [NSString stringWithFormat: @"DELETE FROM %@", [self storeTableName]];
error = [storeChannel evaluateExpressionX:query];
if (error)
[self errorWithFormat: @"%s: cannot delete content '%@': %@",
[self errorWithFormat: @"%s: cannot delete content '%@': %@",
__PRETTY_FUNCTION__, query, error];
else if (!ofFlags.sameTableForQuick) {
/* content row deleted, now delete the quick row */
@@ -1317,7 +1318,7 @@ andAttribute: (EOAttribute *)_attribute
query = [NSString stringWithFormat: @"DELETE FROM %@", [self quickTableName]];
error = [quickChannel evaluateExpressionX: query];
if (error)
[self errorWithFormat: @"%s: cannot delete quick row '%@': %@",
[self errorWithFormat: @"%s: cannot delete quick row '%@': %@",
__PRETTY_FUNCTION__, query, error];
}
@@ -1333,6 +1334,49 @@ andAttribute: (EOAttribute *)_attribute
return error;
}
- (NSException *) purgeDeletedRecordsBefore: (unsigned int) days
{
NSString *delSql, *table;
EOAdaptorContext *adaptorCtx;
EOAdaptorChannel *channel;
NSCalendarDate *nowDate;
unsigned int delta;
channel = [self acquireStoreChannel];
if ((channel = [self acquireStoreChannel]) == nil)
return [NSException exceptionWithName: @"GCSChannelException"
reason: @"could not open storage channel!"
userInfo: nil];
adaptorCtx = [channel adaptorContext];
[adaptorCtx beginTransaction];
table = [self storeTableName];
nowDate = [NSCalendarDate date];
delta = days * 24 * 60 * 60;
if (delta > [nowDate timeIntervalSince1970])
return [NSException exceptionWithName: @"GCSArgumentException"
reason: @"number of days is too high!"
userInfo: nil];
delta = [nowDate timeIntervalSince1970] - delta;
if ([GCSFolderManager singleStoreMode])
delSql = [NSString stringWithFormat: @"DELETE FROM %@"
@" WHERE c_folder_id = %@ AND c_deleted = 1 AND c_lastmodified < %u",
table, folderId, delta];
else
delSql = [NSString stringWithFormat: @"DELETE FROM %@"
@" WHERE c_deleted = 1 AND c_lastmodified < %u",
table, delta];
[channel evaluateExpressionX: delSql];
[[channel adaptorContext] commitTransaction];
[self releaseChannel: channel];
return nil;
}
- (NSException *) touchContentWithName: (NSString *) _name
{
NSString *touchSql, *table;
@@ -1389,14 +1433,14 @@ andAttribute: (EOAttribute *)_attribute
EOAdaptorChannel *channel;
NSString *delsql;
NSString *table;
/* open channels */
if ((channel = [self acquireStoreChannel]) == nil) {
[self errorWithFormat:@"could not open channel!"];
return nil;
}
/* delete rows */
[[channel adaptorContext] beginTransaction];
table = [self storeTableName];
@@ -1423,7 +1467,7 @@ andAttribute: (EOAttribute *)_attribute
delsql = [@"DROP TABLE " stringByAppendingString: table];
[channel evaluateExpressionX:delsql];
}
[[channel adaptorContext] commitTransaction];
[self releaseChannel:channel];
@@ -1437,7 +1481,7 @@ andAttribute: (EOAttribute *)_attribute
EOAdaptorChannel *quickChannel;
EOAdaptorContext *adaptorCtx;
NSException *error;
quickChannel = [self acquireQuickChannel];
adaptorCtx = [quickChannel adaptorContext];
[adaptorCtx beginTransaction];
@@ -1500,15 +1544,15 @@ andAttribute: (EOAttribute *)_attribute
NSArray *attrs;
NSMutableArray *results;
NSDictionary *row;
qualifier = [_fs qualifier];
sortOrderings = [_fs sortOrderings];
#if 0
[self logWithFormat:@"FETCH: %@", _flds];
[self logWithFormat:@" MATCH: %@", _q];
#endif
/* generate SQL */
sql = [NSMutableString stringWithCapacity:256];
@@ -1536,34 +1580,34 @@ andAttribute: (EOAttribute *)_attribute
[sql appendString:@" LIMIT "]; // count
[sql appendString:@" OFFSET "]; // index from 0
#endif
/* open channel */
if ((channel = [self acquireAclChannel]) == nil) {
[self errorWithFormat:@"could not open acl channel!"];
return nil;
}
/* run SQL */
if ((error = [channel evaluateExpressionX:sql]) != nil) {
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
__PRETTY_FUNCTION__, sql, error];
[self releaseChannel:channel];
return nil;
}
/* fetch results */
results = [NSMutableArray arrayWithCapacity:64];
attrs = [channel describeResults:NO /* do not beautify names */];
while ((row = [channel fetchAttributes:attrs withZone:NULL]) != nil)
[results addObject:row];
/* release channels */
[self releaseChannel: channel];
return results;
}
@@ -1602,7 +1646,7 @@ andAttribute: (EOAttribute *)_attribute
NSException *error;
NSMutableString *sql;
NSString *qSql;
sql = [NSMutableString stringWithCapacity:256];
[sql appendString:@"DELETE FROM "];
[sql appendString:[self aclTableName]];
@@ -1620,16 +1664,16 @@ andAttribute: (EOAttribute *)_attribute
[self errorWithFormat:@"could not open acl channel!"];
return;
}
/* run SQL */
[[channel adaptorContext] beginTransaction];
if ((error = [channel evaluateExpressionX:sql]) != nil) {
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
[self errorWithFormat:@"%s: cannot execute acl-fetch SQL '%@': %@",
__PRETTY_FUNCTION__, sql, error];
[self releaseChannel:channel];
return;
}
[[channel adaptorContext] commitTransaction];
[self releaseChannel:channel];
}
@@ -1647,11 +1691,11 @@ andAttribute: (EOAttribute *)_attribute
if ([GCSFolderManager singleStoreMode])
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS CNT FROM %@ WHERE c_folder_id = %@",
@"SELECT COUNT(*) AS cnt FROM %@ WHERE c_folder_id = %@",
[self storeTableName], folderId];
else
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS CNT FROM %@",
@"SELECT COUNT(*) AS cnt FROM %@",
[self storeTableName]];
if (excludeDeleted)
{
@@ -1666,7 +1710,56 @@ andAttribute: (EOAttribute *)_attribute
{
error = [channel evaluateExpressionX: sqlString];
if (error)
[self errorWithFormat: @"%s: cannot execute SQL '%@': %@",
[self errorWithFormat: @"%s: cannot execute SQL '%@': %@",
__PRETTY_FUNCTION__, sqlString, error];
else
{
attrs = [channel describeResults: NO];
row = [channel fetchAttributes: attrs withZone: NULL];
count = [[row objectForKey: @"cnt"] unsignedIntValue];
[channel cancelFetch];
}
[self releaseChannel: channel];
}
return count;
}
- (unsigned int) recordsCountDeletedBefore: (unsigned int) days
{
EOAdaptorChannel *channel;
NSArray *attrs;
NSCalendarDate *nowDate;
NSDictionary *row;
NSException *error;
NSMutableString *sqlString;
unsigned int delta, count;
count = 0;
nowDate = [NSCalendarDate date];
delta = days * 24 * 60 * 60;
if (delta < [nowDate timeIntervalSince1970])
delta = [nowDate timeIntervalSince1970] - delta;
else
delta = 0;
if ([GCSFolderManager singleStoreMode])
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS cnt FROM %@"
@" WHERE c_folder_id = %@ AND c_lastmodified < %u AND c_deleted = 1",
[self storeTableName], folderId, delta];
else
sqlString = [NSMutableString stringWithFormat:
@"SELECT COUNT(*) AS cnt FROM %@"
@" WHERE c_lastmodified < %u AND c_deleted = 1",
[self storeTableName], delta];
channel = [self acquireStoreChannel];
if (channel)
{
error = [channel evaluateExpressionX: sqlString];
if (error)
[self errorWithFormat: @"%s: cannot execute SQL '%@': %@",
__PRETTY_FUNCTION__, sqlString, error];
else
{
@@ -1716,7 +1809,7 @@ andAttribute: (EOAttribute *)_attribute
- (NSString *)description {
NSMutableString *ms;
id tmp;
ms = [NSMutableString stringWithCapacity:256];
[ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])];
@@ -1729,7 +1822,7 @@ andAttribute: (EOAttribute *)_attribute
if ((tmp = [self folderTypeName])) [ms appendFormat:@" type=%@", tmp];
if ((tmp = [self location]))
[ms appendFormat:@" loc=%@", [tmp absoluteString]];
[ms appendString:@">"];
return ms;
}
+1
View File
@@ -77,6 +77,7 @@
- (BOOL)folderExistsAtPath:(NSString *)_path;
- (NSArray *)listSubFoldersAtPath:(NSString *)_path recursive:(BOOL)_flag;
- (NSDictionary *) recordAtPath: (NSString *) _path;
- (GCSFolder *)folderAtPath:(NSString *)_path;
- (NSException *)createFolderOfType:(NSString *)_type withName:(NSString *)_name atPath:(NSString *)_path;
+8 -3
View File
@@ -784,7 +784,7 @@ static BOOL _singleStoreMode = NO;
return result;
}
- (GCSFolder *) folderAtPath: (NSString *) _path
- (NSDictionary *) recordAtPath: (NSString *) _path
{
NSMutableString *sql;
NSArray *fnames, *records;
@@ -841,8 +841,13 @@ static BOOL _singleStoreMode = NO;
[self debugWithFormat:@"found no record for path: '%@'", _path];
return nil;
}
return [self folderForRecord:record];
return record;
}
- (GCSFolder *) folderAtPath: (NSString *) _path
{
return [self folderForRecord: [self recordAtPath: _path]];
}
- (NSString *) baseTableNameWithUID: (NSString *) _uid
+2 -2
View File
@@ -1,6 +1,6 @@
/* CardElement.h - this file is part of SOPE
*
* Copyright (C) 2006-2014 Inverse inc.
* Copyright (C) 2006-2017 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
@@ -64,7 +64,7 @@
- (NSMutableDictionary *) values;
/* ELEM:...;value1,value2,...;... */
- (void) setValues: (NSMutableArray *) newValues
- (void) setValues: (id) newValues
atIndex: (NSUInteger) idx
forKey: (NSString *) key;
+7 -2
View File
@@ -1,6 +1,6 @@
/* CardElement.m - this file is part of SOPE
*
* Copyright (C) 2006-2014 Inverse inc.
* Copyright (C) 2006-2017 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
@@ -130,12 +130,17 @@
return values;
}
- (void) setValues: (NSMutableArray *) newValues
- (void) setValues: (id) newValues
atIndex: (NSUInteger) idx
forKey: (NSString *) key
{
NSMutableArray *oldValues, *subValues;
if (newValues && [newValues isKindOfClass: [NSString class]])
return [self setSingleValue: (NSString *)newValues
atIndex: idx
forKey: key];
oldValues = [self valuesForKey: key];
if (!oldValues)
{
+2 -2
View File
@@ -51,10 +51,10 @@
[aString appendString: @","];
subValue = [self objectAtIndex: count];
/* We MUST quote attribute values that have a ":" in them
/* We MUST quote attribute values that have a ":" or "," in them
and that not already quoted */
if (asAttributes && [subValue length] > 2
&& [subValue rangeOfString: @":"].length
&& ([subValue rangeOfString: @":"].length || [subValue rangeOfString: @","].length)
&& [subValue characterAtIndex: 0] != '"'
&& ![subValue hasSuffix: @"\""])
subValue = [NSString stringWithFormat: @"\"%@\"", subValue];
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Abidjan
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Accra
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Addis_Ababa
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Algiers
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Asmara
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bamako
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bangui
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Banjul
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bissau
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Blantyre
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Brazzaville
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bujumbura
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Cairo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Casablanca
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ceuta
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Conakry
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Dakar
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Dar_es_Salaam
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Djibouti
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Douala
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/El_Aaiun
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Freetown
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Gaborone
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Harare
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Johannesburg
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Juba
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kampala
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Khartoum
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kigali
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kinshasa
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lagos
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Libreville
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lome
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Luanda
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lubumbashi
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lusaka
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Malabo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Maputo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Maseru
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Mbabane
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Mogadishu
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Monrovia
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Nairobi
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ndjamena
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Niamey
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Nouakchott
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ouagadougou
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Porto-Novo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Sao_Tome
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Tripoli
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Tunis
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Windhoek
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Adak
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Anchorage
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Anguilla
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Antigua
+2 -2
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Araguaina
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Araguaina
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:BRT
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Buenos_Aires
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Buenos_Aires
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Catamarca
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Catamarca
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Cordoba
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Cordoba
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Jujuy
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Jujuy
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/La_Rioja
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/La_Rioja
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Mendoza
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Mendoza
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Rio_Gallegos
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Rio_Gallegos
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Salta
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Salta
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/San_Juan
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/San_Juan
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/San_Luis
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/San_Luis
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Tucuman
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Tucuman
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Argentina/Ushuaia
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Argentina/Ushuaia
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:ART
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Aruba
+3 -3
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Asuncion
@@ -7,14 +7,14 @@ X-LIC-LOCATION:America/Asuncion
BEGIN:DAYLIGHT
TZOFFSETFROM:-0400
TZOFFSETTO:-0300
TZNAME:PYST
TZNAME:-03
DTSTART:19701004T000000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0400
TZNAME:PYT
TZNAME:-04
DTSTART:19700322T000000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=4SU
END:STANDARD
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Atikokan
+2 -2
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Bahia
@@ -7,7 +7,7 @@ X-LIC-LOCATION:America/Bahia
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:BRT
TZNAME:-03
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML IANA 2016h//EN
PRODID:-//Inverse inc.//NONSGML IANA 2017b//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Bahia_Banderas
Loaded 100 of 900 files, more files were not shown because too many files have changed in this diff. Show more